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