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