1*c54f35caSApple OSS Distributions /* compile: xcrun -sdk macosx.internal clang -ldarwintest -o o_search o_search.c -g -Weverything */
2*c54f35caSApple OSS Distributions
3*c54f35caSApple OSS Distributions #include <darwintest.h>
4*c54f35caSApple OSS Distributions #include <darwintest_utils.h>
5*c54f35caSApple OSS Distributions #include <darwintest_multiprocess.h>
6*c54f35caSApple OSS Distributions #include <errno.h>
7*c54f35caSApple OSS Distributions #include <stdint.h>
8*c54f35caSApple OSS Distributions #include <stdlib.h>
9*c54f35caSApple OSS Distributions #include <unistd.h>
10*c54f35caSApple OSS Distributions #include <sys/attr.h>
11*c54f35caSApple OSS Distributions #include <sys/event.h>
12*c54f35caSApple OSS Distributions #include <sys/resource.h>
13*c54f35caSApple OSS Distributions #include <dirent.h>
14*c54f35caSApple OSS Distributions
15*c54f35caSApple OSS Distributions #ifndef O_EXEC
16*c54f35caSApple OSS Distributions #define O_EXEC 0x40000000
17*c54f35caSApple OSS Distributions #define O_SEARCH (O_EXEC | O_DIRECTORY)
18*c54f35caSApple OSS Distributions #endif
19*c54f35caSApple OSS Distributions
20*c54f35caSApple OSS Distributions T_GLOBAL_META(
21*c54f35caSApple OSS Distributions T_META_NAMESPACE("xnu.vfs"),
22*c54f35caSApple OSS Distributions T_META_RADAR_COMPONENT_NAME("xnu"),
23*c54f35caSApple OSS Distributions T_META_RADAR_COMPONENT_VERSION("vfs"),
24*c54f35caSApple OSS Distributions T_META_ASROOT(false),
25*c54f35caSApple OSS Distributions T_META_CHECK_LEAKS(false));
26*c54f35caSApple OSS Distributions
27*c54f35caSApple OSS Distributions #define TEST_FILE "testfile"
28*c54f35caSApple OSS Distributions #define NUMDIRS 5
29*c54f35caSApple OSS Distributions
30*c54f35caSApple OSS Distributions static char g_testfile[MAXPATHLEN];
31*c54f35caSApple OSS Distributions
32*c54f35caSApple OSS Distributions extern ssize_t __getdirentries64(int, void *, size_t, off_t *);
33*c54f35caSApple OSS Distributions
34*c54f35caSApple OSS Distributions static void
exit_cleanup(void)35*c54f35caSApple OSS Distributions exit_cleanup(void)
36*c54f35caSApple OSS Distributions {
37*c54f35caSApple OSS Distributions (void)unlink(g_testfile);
38*c54f35caSApple OSS Distributions }
39*c54f35caSApple OSS Distributions
40*c54f35caSApple OSS Distributions T_DECL(o_search,
41*c54f35caSApple OSS Distributions "test O_SEARCH for open",
42*c54f35caSApple OSS Distributions T_META_ASROOT(false))
43*c54f35caSApple OSS Distributions {
44*c54f35caSApple OSS Distributions const char *tmpdir = dt_tmpdir();
45*c54f35caSApple OSS Distributions void *mapped = MAP_FAILED;
46*c54f35caSApple OSS Distributions off_t dirbyte = 0;
47*c54f35caSApple OSS Distributions int retval = 0;
48*c54f35caSApple OSS Distributions int fd = -1;
49*c54f35caSApple OSS Distributions int tmpdir_fd = -1;
50*c54f35caSApple OSS Distributions char namebuf[(sizeof(struct dirent) * (NUMDIRS + 2))];
51*c54f35caSApple OSS Distributions char attrbuf[256];
52*c54f35caSApple OSS Distributions
53*c54f35caSApple OSS Distributions T_SETUPBEGIN;
54*c54f35caSApple OSS Distributions
55*c54f35caSApple OSS Distributions atexit(exit_cleanup);
56*c54f35caSApple OSS Distributions
57*c54f35caSApple OSS Distributions T_ASSERT_POSIX_ZERO(chdir(tmpdir),
58*c54f35caSApple OSS Distributions "Setup: changing to tmpdir: %s", tmpdir);
59*c54f35caSApple OSS Distributions
60*c54f35caSApple OSS Distributions snprintf(g_testfile, MAXPATHLEN, "%s/%s", tmpdir, TEST_FILE);
61*c54f35caSApple OSS Distributions
62*c54f35caSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(fd = open(g_testfile, O_CREAT | O_RDWR, 0644), NULL);
63*c54f35caSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(retval = (int)write(fd, g_testfile, sizeof(g_testfile)), "Write: %s", g_testfile);
64*c54f35caSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(close(fd), "Close test file: %s", g_testfile);
65*c54f35caSApple OSS Distributions
66*c54f35caSApple OSS Distributions T_SETUPEND;
67*c54f35caSApple OSS Distributions
68*c54f35caSApple OSS Distributions T_WITH_ERRNO;
69*c54f35caSApple OSS Distributions tmpdir_fd = open(tmpdir, O_EXEC);
70*c54f35caSApple OSS Distributions T_ASSERT_TRUE((tmpdir_fd == -1) && (errno == EISDIR),
71*c54f35caSApple OSS Distributions "Trying to open directory O_EXEC: %s, tmpdir_fd = %d, errno = %d", g_testfile, tmpdir_fd, errno);
72*c54f35caSApple OSS Distributions
73*c54f35caSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(tmpdir_fd = open(tmpdir, O_RDONLY), NULL);
74*c54f35caSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(retval = (int)__getdirentries64(tmpdir_fd, namebuf, sizeof(namebuf), &dirbyte), NULL);
75*c54f35caSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(close(tmpdir_fd), NULL);
76*c54f35caSApple OSS Distributions
77*c54f35caSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(tmpdir_fd = open(tmpdir, O_SEARCH), NULL);
78*c54f35caSApple OSS Distributions retval = (int)__getdirentries64(tmpdir_fd, namebuf, sizeof(namebuf), &dirbyte);
79*c54f35caSApple OSS Distributions T_ASSERT_TRUE((retval == -1) && (errno == EBADF),
80*c54f35caSApple OSS Distributions "Trying to read directory opened with O_SEARCH: %s, retval = %d, errno = %d",
81*c54f35caSApple OSS Distributions tmpdir, retval, errno);
82*c54f35caSApple OSS Distributions
83*c54f35caSApple OSS Distributions fd = openat(tmpdir_fd, TEST_FILE, O_EXEC);
84*c54f35caSApple OSS Distributions T_ASSERT_TRUE((fd == -1) && (errno == EACCES),
85*c54f35caSApple OSS Distributions "Trying to open file for execute with perms 644: %s, retval = %d, errno = %d",
86*c54f35caSApple OSS Distributions tmpdir, retval, errno);
87*c54f35caSApple OSS Distributions
88*c54f35caSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(retval = fchmodat(tmpdir_fd, TEST_FILE, 0744, 0), NULL);
89*c54f35caSApple OSS Distributions
90*c54f35caSApple OSS Distributions fd = openat(tmpdir_fd, TEST_FILE, O_SEARCH);
91*c54f35caSApple OSS Distributions T_ASSERT_TRUE((fd == -1) && (errno == ENOTDIR),
92*c54f35caSApple OSS Distributions "Trying to open file for execute with perms 644: %s, retval = %d, errno = %d",
93*c54f35caSApple OSS Distributions tmpdir, retval, errno);
94*c54f35caSApple OSS Distributions
95*c54f35caSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(fd = openat(tmpdir_fd, TEST_FILE, O_EXEC), NULL);
96*c54f35caSApple OSS Distributions
97*c54f35caSApple OSS Distributions retval = (int)read(fd, &attrbuf, 2);
98*c54f35caSApple OSS Distributions T_ASSERT_TRUE((retval == -1) && (errno == EBADF),
99*c54f35caSApple OSS Distributions "Trying to read file opened with O_EXEC: %s, retval = %d, errno = %d",
100*c54f35caSApple OSS Distributions g_testfile, retval, errno);
101*c54f35caSApple OSS Distributions
102*c54f35caSApple OSS Distributions retval = (int)write(fd, &attrbuf, 2);
103*c54f35caSApple OSS Distributions T_ASSERT_TRUE((retval == -1) && (errno == EBADF),
104*c54f35caSApple OSS Distributions "Trying to write file opened with O_EXEC: %s, retval = %d, errno = %d",
105*c54f35caSApple OSS Distributions g_testfile, retval, errno);
106*c54f35caSApple OSS Distributions
107*c54f35caSApple OSS Distributions mapped = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_SHARED,
108*c54f35caSApple OSS Distributions fd, 0);
109*c54f35caSApple OSS Distributions T_ASSERT_TRUE((mapped == MAP_FAILED) && (errno == EACCES),
110*c54f35caSApple OSS Distributions "Trying to mmap file for read opened with O_EXEC: %s, mapped = %ld, errno = %d",
111*c54f35caSApple OSS Distributions g_testfile, (long)mapped, errno);
112*c54f35caSApple OSS Distributions
113*c54f35caSApple OSS Distributions mapped = mmap(NULL, PAGE_SIZE, PROT_WRITE, MAP_SHARED,
114*c54f35caSApple OSS Distributions fd, 0);
115*c54f35caSApple OSS Distributions T_ASSERT_TRUE((mapped == MAP_FAILED) && (errno == EACCES),
116*c54f35caSApple OSS Distributions "Trying to mmap file for write opened with O_EXEC: %s, mapped = %ld, errno = %d",
117*c54f35caSApple OSS Distributions g_testfile, (long)mapped, errno);
118*c54f35caSApple OSS Distributions
119*c54f35caSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(close(fd), NULL);
120*c54f35caSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(close(tmpdir_fd), NULL);
121*c54f35caSApple OSS Distributions }
122