1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (c) 2014 Fujitsu Ltd.
4 * Author: Zeng Linggang <[email protected]>
5 */
6
7 /*\
8 * [Description]
9 *
10 * Verify that readdir will fail with:
11 *
12 * - ENOENT when passed a fd to a deleted directory
13 * - ENOTDIR when passed fd that does not point to a directory
14 * - EBADFD when passed an invalid fd
15 * - EFAULT when passed invalid buffer pointer
16 */
17
18 #include <sys/stat.h>
19 #include "tst_test.h"
20 #include "lapi/syscalls.h"
21 #include "lapi/readdir.h"
22
23 #define TEST_DIR "test_dir"
24 #define TEST_DIR4 "test_dir4"
25 #define TEST_FILE "test_file"
26 #define DIR_MODE 0755
27
28 static unsigned int del_dir_fd, file_fd;
29 static unsigned int invalid_fd = 999;
30 static unsigned int dir_fd;
31 static struct old_linux_dirent dirp;
32
33 static struct tcase {
34 unsigned int *fd;
35 struct old_linux_dirent *dirp;
36 unsigned int count;
37 int exp_errno;
38 char *desc;
39 } tcases[] = {
40 {&del_dir_fd, &dirp, sizeof(struct old_linux_dirent), ENOENT, "directory deleted"},
41 {&file_fd, &dirp, sizeof(struct old_linux_dirent), ENOTDIR, "not a directory"},
42 {&invalid_fd, &dirp, sizeof(struct old_linux_dirent), EBADF, "invalid fd"},
43 {&dir_fd, (struct old_linux_dirent *)-1,
44 sizeof(struct old_linux_dirent), EFAULT, "invalid buffer pointer"},
45 };
46
setup(void)47 static void setup(void)
48 {
49 unsigned int i;
50
51 SAFE_MKDIR(TEST_DIR, DIR_MODE);
52 del_dir_fd = SAFE_OPEN(TEST_DIR, O_RDONLY | O_DIRECTORY);
53 SAFE_RMDIR(TEST_DIR);
54
55 file_fd = SAFE_OPEN(TEST_FILE, O_RDWR | O_CREAT, 0777);
56
57 SAFE_MKDIR(TEST_DIR4, DIR_MODE);
58 dir_fd = SAFE_OPEN(TEST_DIR4, O_RDONLY | O_DIRECTORY);
59
60 for (i = 0; i < ARRAY_SIZE(tcases); i++) {
61 if (tcases[i].exp_errno == EFAULT)
62 tcases[i].dirp = tst_get_bad_addr(NULL);
63 }
64 }
65
verify_readdir(unsigned int nr)66 static void verify_readdir(unsigned int nr)
67 {
68 struct tcase *tc = &tcases[nr];
69
70 TST_EXP_FAIL(tst_syscall(__NR_readdir, *tc->fd, tc->dirp, tc->count),
71 tc->exp_errno, "readdir() with %s", tc->desc);
72 }
73
74 static struct tst_test test = {
75 .tcnt = ARRAY_SIZE(tcases),
76 .setup = setup,
77 .test = verify_readdir,
78 .needs_tmpdir = 1,
79 };
80