xref: /xnu-12377.81.4/tests/ipc/mach_port_construct_errors.c (revision 043036a2b3718f7f0be807e2870f8f47d3fa0796)
1*043036a2SApple OSS Distributions #include <stdio.h>
2*043036a2SApple OSS Distributions #include <stdlib.h>
3*043036a2SApple OSS Distributions #include <mach/mach.h>
4*043036a2SApple OSS Distributions #include <mach/mach_port.h>
5*043036a2SApple OSS Distributions #include <sys/code_signing.h>
6*043036a2SApple OSS Distributions #include <sys/sysctl.h>
7*043036a2SApple OSS Distributions #include <darwintest.h>
8*043036a2SApple OSS Distributions 
9*043036a2SApple OSS Distributions T_GLOBAL_META(
10*043036a2SApple OSS Distributions 	T_META_NAMESPACE("xnu.ipc"),
11*043036a2SApple OSS Distributions 	T_META_RUN_CONCURRENTLY(TRUE),
12*043036a2SApple OSS Distributions 	T_META_RADAR_COMPONENT_NAME("xnu"),
13*043036a2SApple OSS Distributions 	T_META_RADAR_COMPONENT_VERSION("IPC"),
14*043036a2SApple OSS Distributions 	T_META_TAG_VM_PREFERRED);
15*043036a2SApple OSS Distributions 
16*043036a2SApple OSS Distributions #define countof(x) (sizeof(x) / sizeof(x[0]))
17*043036a2SApple OSS Distributions 
18*043036a2SApple OSS Distributions static void
19*043036a2SApple OSS Distributions expect_sigkill(
20*043036a2SApple OSS Distributions 	void (^fn)(void),
21*043036a2SApple OSS Distributions 	const char *description)
22*043036a2SApple OSS Distributions {
23*043036a2SApple OSS Distributions 	pid_t pid = fork();
24*043036a2SApple OSS Distributions 	T_QUIET; T_ASSERT_POSIX_SUCCESS(pid, "fork");
25*043036a2SApple OSS Distributions 
26*043036a2SApple OSS Distributions 	if (pid == 0) {
27*043036a2SApple OSS Distributions 		fn();
28*043036a2SApple OSS Distributions 		T_ASSERT_FAIL("%s: did not receive SIGKILL", description);
29*043036a2SApple OSS Distributions 	} else {
30*043036a2SApple OSS Distributions 		int status = 0;
31*043036a2SApple OSS Distributions 		T_QUIET; T_ASSERT_POSIX_SUCCESS(waitpid(pid, &status, 0), "waitpid");
32*043036a2SApple OSS Distributions 		T_EXPECT_EQ(WTERMSIG(status), SIGKILL,
33*043036a2SApple OSS Distributions 		    "%s exited with %d, expect SIGKILL", description, WTERMSIG(status));
34*043036a2SApple OSS Distributions 	}
35*043036a2SApple OSS Distributions }
36*043036a2SApple OSS Distributions 
37*043036a2SApple OSS Distributions T_DECL(mach_port_construct_at_most_one,
38*043036a2SApple OSS Distributions     "mach_port_construct at most one flag policy")
39*043036a2SApple OSS Distributions {
40*043036a2SApple OSS Distributions 	/* verify our at most one flag rule is enforced */
41*043036a2SApple OSS Distributions 	const uint32_t at_most_one_flags[] = {
42*043036a2SApple OSS Distributions 		MPO_REPLY_PORT,
43*043036a2SApple OSS Distributions 		MPO_CONNECTION_PORT,
44*043036a2SApple OSS Distributions 		MPO_SERVICE_PORT,
45*043036a2SApple OSS Distributions 		MPO_PROVISIONAL_REPLY_PORT,
46*043036a2SApple OSS Distributions 		MPO_EXCEPTION_PORT,
47*043036a2SApple OSS Distributions 		MPO_CONNECTION_PORT_WITH_PORT_ARRAY
48*043036a2SApple OSS Distributions 	};
49*043036a2SApple OSS Distributions 
50*043036a2SApple OSS Distributions 
51*043036a2SApple OSS Distributions 	for (uint32_t i = 0; i < countof(at_most_one_flags) - 1; ++i) {
52*043036a2SApple OSS Distributions 		for (uint32_t j = i + 1; j < countof(at_most_one_flags); ++j) {
53*043036a2SApple OSS Distributions 			mach_port_t port;
54*043036a2SApple OSS Distributions 
55*043036a2SApple OSS Distributions 			mach_port_options_t opts = {
56*043036a2SApple OSS Distributions 				.flags = at_most_one_flags[i] | at_most_one_flags[j]
57*043036a2SApple OSS Distributions 			};
58*043036a2SApple OSS Distributions 
59*043036a2SApple OSS Distributions 			kern_return_t kr = mach_port_construct(mach_task_self(), &opts, 0x0, &port);
60*043036a2SApple OSS Distributions 			T_ASSERT_MACH_ERROR(kr,
61*043036a2SApple OSS Distributions 			    KERN_INVALID_ARGUMENT, "mach_port_construct failed for at most one flags");
62*043036a2SApple OSS Distributions 		}
63*043036a2SApple OSS Distributions 	}
64*043036a2SApple OSS Distributions }
65*043036a2SApple OSS Distributions 
66*043036a2SApple OSS Distributions T_DECL(mach_port_construct_invalid_arguments_and_values,
67*043036a2SApple OSS Distributions     "mach_port_construct invalid arguments and values")
68*043036a2SApple OSS Distributions {
69*043036a2SApple OSS Distributions 	kern_return_t kr;
70*043036a2SApple OSS Distributions 	mach_port_t port;
71*043036a2SApple OSS Distributions 
72*043036a2SApple OSS Distributions 	mach_port_options_t conn_opts = {
73*043036a2SApple OSS Distributions 		.flags = MPO_CONNECTION_PORT,
74*043036a2SApple OSS Distributions 		.service_port_name = 0x0
75*043036a2SApple OSS Distributions 	};
76*043036a2SApple OSS Distributions 
77*043036a2SApple OSS Distributions 	kr = mach_port_construct(mach_task_self(), &conn_opts, 0x0, &port);
78*043036a2SApple OSS Distributions 	T_ASSERT_MACH_ERROR(kr,
79*043036a2SApple OSS Distributions 	    KERN_INVALID_ARGUMENT,
80*043036a2SApple OSS Distributions 	    "MPO_CONNECTION_PORT failed on service_port_name");
81*043036a2SApple OSS Distributions 
82*043036a2SApple OSS Distributions 	conn_opts.service_port_name = MPO_ANONYMOUS_SERVICE;
83*043036a2SApple OSS Distributions 
84*043036a2SApple OSS Distributions 	kr = mach_port_construct(mach_task_self(), &conn_opts, 0x0, &port);
85*043036a2SApple OSS Distributions 	T_ASSERT_MACH_SUCCESS(kr, "MPO_CONNECTION_PORT succeeds with anonymous service name");
86*043036a2SApple OSS Distributions 	kr = mach_port_destruct(mach_task_self(), port, 0, 0);
87*043036a2SApple OSS Distributions 	T_ASSERT_MACH_SUCCESS(kr, "destroy anonymous service name");
88*043036a2SApple OSS Distributions 
89*043036a2SApple OSS Distributions 	mach_port_options_t qlimit_opts = {
90*043036a2SApple OSS Distributions 		.flags = MPO_QLIMIT,
91*043036a2SApple OSS Distributions 		.mpl.mpl_qlimit = MACH_PORT_QLIMIT_MAX + 1
92*043036a2SApple OSS Distributions 	};
93*043036a2SApple OSS Distributions 
94*043036a2SApple OSS Distributions 	kr = mach_port_construct(mach_task_self(), &qlimit_opts, 0x0, &port);
95*043036a2SApple OSS Distributions 	T_ASSERT_MACH_ERROR(kr,
96*043036a2SApple OSS Distributions 	    KERN_INVALID_VALUE,
97*043036a2SApple OSS Distributions 	    "MPO_QLIMIT failed on invalid value");
98*043036a2SApple OSS Distributions 
99*043036a2SApple OSS Distributions 	/* Enumerate on all unknown MPO flags */
100*043036a2SApple OSS Distributions 	mach_port_options_t unknown_flags_opts;
101*043036a2SApple OSS Distributions 	for (uint32_t i = 0; i < sizeof(unknown_flags_opts.flags) * CHAR_BIT; ++i) {
102*043036a2SApple OSS Distributions 		unknown_flags_opts.flags = MPO_UNUSED_BITS & (1 << i);
103*043036a2SApple OSS Distributions 
104*043036a2SApple OSS Distributions 		if (unknown_flags_opts.flags != 0) {
105*043036a2SApple OSS Distributions 			kr = mach_port_construct(mach_task_self(), &unknown_flags_opts, 0x0, &port);
106*043036a2SApple OSS Distributions 			T_ASSERT_MACH_ERROR(kr,
107*043036a2SApple OSS Distributions 			    KERN_INVALID_ARGUMENT,
108*043036a2SApple OSS Distributions 			    "Unknown MPO flags 0x%x failed with KERN_INVALID_ARGUMENT",
109*043036a2SApple OSS Distributions 			    unknown_flags_opts.flags);
110*043036a2SApple OSS Distributions 		}
111*043036a2SApple OSS Distributions 	}
112*043036a2SApple OSS Distributions }
113*043036a2SApple OSS Distributions 
114*043036a2SApple OSS Distributions T_DECL(mach_port_construct_fatal_failure,
115*043036a2SApple OSS Distributions     "mach_port_construct kern defined fatal failures",
116*043036a2SApple OSS Distributions     T_META_IGNORECRASHES(".*mach_port_construct_errors.*"),
117*043036a2SApple OSS Distributions     T_META_ENABLED(!TARGET_OS_OSX && !TARGET_OS_BRIDGE))
118*043036a2SApple OSS Distributions {
119*043036a2SApple OSS Distributions 	expect_sigkill(^{
120*043036a2SApple OSS Distributions 		mach_port_t port;
121*043036a2SApple OSS Distributions 		mach_port_options_t opts = {
122*043036a2SApple OSS Distributions 		        .flags = MPO_CONNECTION_PORT_WITH_PORT_ARRAY
123*043036a2SApple OSS Distributions 		};
124*043036a2SApple OSS Distributions 		(void)mach_port_construct(mach_task_self(), &opts, 0x0, &port);
125*043036a2SApple OSS Distributions 	}, "passing MPO_CONNECTION_PORT_WITH_PORT_ARRAY without entitlement");
126*043036a2SApple OSS Distributions }
127*043036a2SApple OSS Distributions 
128*043036a2SApple OSS Distributions T_DECL(mach_port_construct_kern_denied,
129*043036a2SApple OSS Distributions     "mach_port_construct kern defined failures",
130*043036a2SApple OSS Distributions     T_META_TAG_VM_PREFERRED,
131*043036a2SApple OSS Distributions     T_META_ENABLED(!TARGET_OS_OSX && !TARGET_OS_BRIDGE))
132*043036a2SApple OSS Distributions {
133*043036a2SApple OSS Distributions 	kern_return_t kr;
134*043036a2SApple OSS Distributions 	mach_port_t port;
135*043036a2SApple OSS Distributions 	mach_port_options_t opts;
136*043036a2SApple OSS Distributions 
137*043036a2SApple OSS Distributions 	/*
138*043036a2SApple OSS Distributions 	 * should fail because only TASK_GRAPHICS_SERVER is allowed to
139*043036a2SApple OSS Distributions 	 * use MPO_TG_BLOCK_TRACKING.
140*043036a2SApple OSS Distributions 	 */
141*043036a2SApple OSS Distributions 	opts.flags = MPO_TG_BLOCK_TRACKING;
142*043036a2SApple OSS Distributions 
143*043036a2SApple OSS Distributions 	kr = mach_port_construct(mach_task_self(), &opts, 0x0, &port);
144*043036a2SApple OSS Distributions 	T_ASSERT_MACH_ERROR(kr,
145*043036a2SApple OSS Distributions 	    KERN_DENIED, "MPO_TG_BLOCK_TRACKING failed with KERN_DENIED");
146*043036a2SApple OSS Distributions }
147