1*c54f35caSApple OSS Distributions /* compile: xcrun -sdk macosx.internal clang -ldarwintest -o iopolicy iopolicy.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
14*c54f35caSApple OSS Distributions #ifndef IOPOL_TYPE_VFS_DISALLOW_RW_FOR_O_EVTONLY
15*c54f35caSApple OSS Distributions #define IOPOL_TYPE_VFS_DISALLOW_RW_FOR_O_EVTONLY 10
16*c54f35caSApple OSS Distributions #endif
17*c54f35caSApple OSS Distributions
18*c54f35caSApple OSS Distributions #ifndef IOPOL_VFS_DISALLOW_RW_FOR_O_EVTONLY_OFF
19*c54f35caSApple OSS Distributions #define IOPOL_VFS_DISALLOW_RW_FOR_O_EVTONLY_OFF 0
20*c54f35caSApple OSS Distributions #endif
21*c54f35caSApple OSS Distributions
22*c54f35caSApple OSS Distributions #ifndef IOPOL_VFS_DISALLOW_RW_FOR_O_EVTONLY_ON
23*c54f35caSApple OSS Distributions #define IOPOL_VFS_DISALLOW_RW_FOR_O_EVTONLY_ON 1
24*c54f35caSApple OSS Distributions #endif
25*c54f35caSApple OSS Distributions
26*c54f35caSApple OSS Distributions T_GLOBAL_META(
27*c54f35caSApple OSS Distributions T_META_NAMESPACE("xnu.vfs.iopolicy"),
28*c54f35caSApple OSS Distributions T_META_RADAR_COMPONENT_NAME("xnu"),
29*c54f35caSApple OSS Distributions T_META_RADAR_COMPONENT_VERSION("vfs"),
30*c54f35caSApple OSS Distributions T_META_CHECK_LEAKS(false));
31*c54f35caSApple OSS Distributions
32*c54f35caSApple OSS Distributions #define TEST_FILE "testfile"
33*c54f35caSApple OSS Distributions
34*c54f35caSApple OSS Distributions static char g_testfile[MAXPATHLEN];
35*c54f35caSApple OSS Distributions static char g_testdata[1024];
36*c54f35caSApple OSS Distributions
37*c54f35caSApple OSS Distributions static void
exit_cleanup(void)38*c54f35caSApple OSS Distributions exit_cleanup(void)
39*c54f35caSApple OSS Distributions {
40*c54f35caSApple OSS Distributions (void)remove(g_testfile);
41*c54f35caSApple OSS Distributions }
42*c54f35caSApple OSS Distributions
43*c54f35caSApple OSS Distributions T_DECL(iopol_type_vfs_disallow_rw_for_o_evtonly,
44*c54f35caSApple OSS Distributions "test IOPOL_TYPE_VFS_DISALLOW_RW_FOR_O_EVTONLY policy")
45*c54f35caSApple OSS Distributions {
46*c54f35caSApple OSS Distributions char attrbuf[256];
47*c54f35caSApple OSS Distributions struct attrlist attrlist;
48*c54f35caSApple OSS Distributions struct kevent vnode_kevent;
49*c54f35caSApple OSS Distributions struct timespec kevent_timeout;
50*c54f35caSApple OSS Distributions const char *tmpdir = dt_tmpdir();
51*c54f35caSApple OSS Distributions void *mapped;
52*c54f35caSApple OSS Distributions int err, fd, kq;
53*c54f35caSApple OSS Distributions
54*c54f35caSApple OSS Distributions T_SETUPBEGIN;
55*c54f35caSApple OSS Distributions
56*c54f35caSApple OSS Distributions atexit(exit_cleanup);
57*c54f35caSApple OSS Distributions
58*c54f35caSApple OSS Distributions T_ASSERT_POSIX_ZERO(chdir(tmpdir),
59*c54f35caSApple OSS Distributions "Setup: changing to tmpdir: %s", tmpdir);
60*c54f35caSApple OSS Distributions
61*c54f35caSApple OSS Distributions snprintf(g_testfile, MAXPATHLEN, "%s/%s", tmpdir, TEST_FILE);
62*c54f35caSApple OSS Distributions
63*c54f35caSApple OSS Distributions T_WITH_ERRNO;
64*c54f35caSApple OSS Distributions fd = open(g_testfile, O_CREAT | O_RDWR, 0666);
65*c54f35caSApple OSS Distributions T_ASSERT_NE(fd, -1, "Create test file: %s", g_testfile);
66*c54f35caSApple OSS Distributions
67*c54f35caSApple OSS Distributions T_WITH_ERRNO;
68*c54f35caSApple OSS Distributions err = (int)write(fd, g_testfile, sizeof(g_testfile));
69*c54f35caSApple OSS Distributions T_ASSERT_NE(err, -1, "Write: %s", g_testfile);
70*c54f35caSApple OSS Distributions
71*c54f35caSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(close(fd), "Close test file: %s", g_testfile);
72*c54f35caSApple OSS Distributions
73*c54f35caSApple OSS Distributions kq = kqueue();
74*c54f35caSApple OSS Distributions T_ASSERT_NE(kq, -1, "Create kqueue");
75*c54f35caSApple OSS Distributions
76*c54f35caSApple OSS Distributions T_SETUPEND;
77*c54f35caSApple OSS Distributions
78*c54f35caSApple OSS Distributions T_WITH_ERRNO;
79*c54f35caSApple OSS Distributions err = setiopolicy_np(IOPOL_TYPE_VFS_DISALLOW_RW_FOR_O_EVTONLY,
80*c54f35caSApple OSS Distributions IOPOL_SCOPE_THREAD, IOPOL_VFS_DISALLOW_RW_FOR_O_EVTONLY_ON);
81*c54f35caSApple OSS Distributions T_ASSERT_TRUE((err == -1) && (errno == EINVAL),
82*c54f35caSApple OSS Distributions "setiopolicy_np(IOPOL_TYPE_VFS_DISALLOW_RW_FOR_O_EVTONLY, IOPOL_SCOPE_THREAD, 1)");
83*c54f35caSApple OSS Distributions
84*c54f35caSApple OSS Distributions T_WITH_ERRNO;
85*c54f35caSApple OSS Distributions err = setiopolicy_np(IOPOL_TYPE_VFS_DISALLOW_RW_FOR_O_EVTONLY,
86*c54f35caSApple OSS Distributions IOPOL_SCOPE_PROCESS, IOPOL_VFS_DISALLOW_RW_FOR_O_EVTONLY_ON);
87*c54f35caSApple OSS Distributions T_ASSERT_NE(err, -1,
88*c54f35caSApple OSS Distributions "setiopolicy_np(IOPOL_TYPE_VFS_DISALLOW_RW_FOR_O_EVTONLY, IOPOL_SCOPE_PROCESS, 1)");
89*c54f35caSApple OSS Distributions
90*c54f35caSApple OSS Distributions T_WITH_ERRNO;
91*c54f35caSApple OSS Distributions err = getiopolicy_np(IOPOL_TYPE_VFS_DISALLOW_RW_FOR_O_EVTONLY,
92*c54f35caSApple OSS Distributions IOPOL_SCOPE_PROCESS);
93*c54f35caSApple OSS Distributions T_ASSERT_EQ(err, IOPOL_VFS_DISALLOW_RW_FOR_O_EVTONLY_ON,
94*c54f35caSApple OSS Distributions "getiopolicy_np(IOPOL_TYPE_VFS_DISALLOW_RW_FOR_O_EVTONLY, IOPOL_SCOPE_PROCESS)");
95*c54f35caSApple OSS Distributions
96*c54f35caSApple OSS Distributions T_WITH_ERRNO;
97*c54f35caSApple OSS Distributions err = setiopolicy_np(IOPOL_TYPE_VFS_DISALLOW_RW_FOR_O_EVTONLY,
98*c54f35caSApple OSS Distributions IOPOL_SCOPE_PROCESS, IOPOL_VFS_DISALLOW_RW_FOR_O_EVTONLY_OFF);
99*c54f35caSApple OSS Distributions T_ASSERT_TRUE((err == -1) && (errno == EINVAL),
100*c54f35caSApple OSS Distributions "setiopolicy_np(IOPOL_TYPE_VFS_DISALLOW_RW_FOR_O_EVTONLY, IOPOL_SCOPE_PROCESS, 0)");
101*c54f35caSApple OSS Distributions
102*c54f35caSApple OSS Distributions T_WITH_ERRNO;
103*c54f35caSApple OSS Distributions fd = open(g_testfile, O_RDWR | O_EVTONLY, 0666);
104*c54f35caSApple OSS Distributions T_ASSERT_NE(fd, -1, "Open test fi1e in 'O_RDW|O_EVTONLY': %s", g_testfile);
105*c54f35caSApple OSS Distributions
106*c54f35caSApple OSS Distributions T_WITH_ERRNO;
107*c54f35caSApple OSS Distributions err = (int)write(fd, g_testdata, sizeof(g_testdata));
108*c54f35caSApple OSS Distributions T_ASSERT_TRUE((err == -1) && (errno == EBADF),
109*c54f35caSApple OSS Distributions "Trying to write: %s", g_testfile);
110*c54f35caSApple OSS Distributions
111*c54f35caSApple OSS Distributions T_WITH_ERRNO;
112*c54f35caSApple OSS Distributions err = (int)read(fd, g_testdata, sizeof(g_testdata));
113*c54f35caSApple OSS Distributions T_ASSERT_TRUE((err == -1) && (errno == EBADF),
114*c54f35caSApple OSS Distributions "Trying to read: %s", g_testfile);
115*c54f35caSApple OSS Distributions
116*c54f35caSApple OSS Distributions T_WITH_ERRNO;
117*c54f35caSApple OSS Distributions mapped = mmap(NULL, sizeof(g_testdata), PROT_READ | PROT_WRITE, MAP_SHARED,
118*c54f35caSApple OSS Distributions fd, 0);
119*c54f35caSApple OSS Distributions T_ASSERT_TRUE((err == -1) && (errno == EACCES),
120*c54f35caSApple OSS Distributions "Trying to mmaped read/write: %s", g_testfile);
121*c54f35caSApple OSS Distributions
122*c54f35caSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(close(fd), "Close test file: %s", g_testfile);
123*c54f35caSApple OSS Distributions
124*c54f35caSApple OSS Distributions T_WITH_ERRNO;
125*c54f35caSApple OSS Distributions fd = open(g_testfile, O_EVTONLY, 0666);
126*c54f35caSApple OSS Distributions T_ASSERT_NE(fd, -1, "Open test fi1e in 'O_EVTONLY': %s", g_testfile);
127*c54f35caSApple OSS Distributions
128*c54f35caSApple OSS Distributions T_WITH_ERRNO;
129*c54f35caSApple OSS Distributions err = (int)read(fd, g_testdata, sizeof(g_testdata));
130*c54f35caSApple OSS Distributions T_ASSERT_TRUE((err == -1) && (errno == EBADF),
131*c54f35caSApple OSS Distributions "Trying to read: %s", g_testfile);
132*c54f35caSApple OSS Distributions
133*c54f35caSApple OSS Distributions T_WITH_ERRNO;
134*c54f35caSApple OSS Distributions memset(&attrlist, 0, sizeof(attrlist));
135*c54f35caSApple OSS Distributions attrlist.bitmapcount = ATTR_BIT_MAP_COUNT;
136*c54f35caSApple OSS Distributions attrlist.commonattr = (ATTR_CMN_OBJTYPE | ATTR_CMN_OBJID | ATTR_CMN_MODTIME);
137*c54f35caSApple OSS Distributions
138*c54f35caSApple OSS Distributions err = fgetattrlist(fd, &attrlist, &attrbuf, sizeof(attrbuf), 0);
139*c54f35caSApple OSS Distributions T_ASSERT_NE(err, -1, "Perform getattrlist: %s", g_testfile);
140*c54f35caSApple OSS Distributions
141*c54f35caSApple OSS Distributions kevent_timeout.tv_sec = kevent_timeout.tv_nsec = 0;
142*c54f35caSApple OSS Distributions EV_SET(&vnode_kevent, fd, EVFILT_VNODE, (EV_ADD | EV_ENABLE | EV_CLEAR),
143*c54f35caSApple OSS Distributions NOTE_WRITE, 0, (void *)g_testfile);
144*c54f35caSApple OSS Distributions err = kevent(kq, &vnode_kevent, 1, NULL, 0, &kevent_timeout);
145*c54f35caSApple OSS Distributions T_ASSERT_GE(err, 0, "Register vnode event on kq: %d", kq);
146*c54f35caSApple OSS Distributions
147*c54f35caSApple OSS Distributions kevent_timeout.tv_sec = 2;
148*c54f35caSApple OSS Distributions kevent_timeout.tv_nsec = 0;
149*c54f35caSApple OSS Distributions EV_SET(&vnode_kevent, fd, EVFILT_VNODE, EV_CLEAR, 0, 0, 0);
150*c54f35caSApple OSS Distributions
151*c54f35caSApple OSS Distributions err = kevent(kq, NULL, 0, &vnode_kevent, 1, &kevent_timeout);
152*c54f35caSApple OSS Distributions T_ASSERT_NE(err, -1, "Listen for vnode event on kq: %d", kq);
153*c54f35caSApple OSS Distributions
154*c54f35caSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(close(fd), "Close test file: %s", g_testfile);
155*c54f35caSApple OSS Distributions }
156