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