1*e3723e1fSApple OSS Distributions #include <stdlib.h>
2*e3723e1fSApple OSS Distributions #include <stdio.h>
3*e3723e1fSApple OSS Distributions #include <pthread.h>
4*e3723e1fSApple OSS Distributions #include <unistd.h>
5*e3723e1fSApple OSS Distributions #include <mach/kern_return.h>
6*e3723e1fSApple OSS Distributions #include <mach/mach.h>
7*e3723e1fSApple OSS Distributions #include <mach/task.h>
8*e3723e1fSApple OSS Distributions #include <mach/thread_status.h>
9*e3723e1fSApple OSS Distributions #include <os/tsd.h>
10*e3723e1fSApple OSS Distributions #include <assert.h>
11*e3723e1fSApple OSS Distributions #include <sys/codesign.h>
12*e3723e1fSApple OSS Distributions #include <stdbool.h>
13*e3723e1fSApple OSS Distributions
14*e3723e1fSApple OSS Distributions #include "cs_helpers.h"
15*e3723e1fSApple OSS Distributions
16*e3723e1fSApple OSS Distributions #define MAX_TEST_NUM 11
17*e3723e1fSApple OSS Distributions
18*e3723e1fSApple OSS Distributions #if __arm64__
19*e3723e1fSApple OSS Distributions #define machine_thread_state_t arm_thread_state64_t
20*e3723e1fSApple OSS Distributions #define EXCEPTION_THREAD_STATE ARM_THREAD_STATE64
21*e3723e1fSApple OSS Distributions #define EXCEPTION_THREAD_STATE_COUNT ARM_THREAD_STATE64_COUNT
22*e3723e1fSApple OSS Distributions #elif __x86_64__
23*e3723e1fSApple OSS Distributions #define machine_thread_state_t x86_thread_state_t
24*e3723e1fSApple OSS Distributions #define EXCEPTION_THREAD_STATE x86_THREAD_STATE
25*e3723e1fSApple OSS Distributions #define EXCEPTION_THREAD_STATE_COUNT x86_THREAD_STATE_COUNT
26*e3723e1fSApple OSS Distributions #else
27*e3723e1fSApple OSS Distributions #error Unsupported architecture
28*e3723e1fSApple OSS Distributions #endif
29*e3723e1fSApple OSS Distributions
30*e3723e1fSApple OSS Distributions static mach_port_t
alloc_server_port(void)31*e3723e1fSApple OSS Distributions alloc_server_port(void)
32*e3723e1fSApple OSS Distributions {
33*e3723e1fSApple OSS Distributions mach_port_t server_port = MACH_PORT_NULL;
34*e3723e1fSApple OSS Distributions kern_return_t kr;
35*e3723e1fSApple OSS Distributions
36*e3723e1fSApple OSS Distributions kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &server_port);
37*e3723e1fSApple OSS Distributions assert(kr == 0);
38*e3723e1fSApple OSS Distributions
39*e3723e1fSApple OSS Distributions kr = mach_port_insert_right(mach_task_self(), server_port, server_port, MACH_MSG_TYPE_MAKE_SEND);
40*e3723e1fSApple OSS Distributions assert(kr == 0);
41*e3723e1fSApple OSS Distributions
42*e3723e1fSApple OSS Distributions return server_port;
43*e3723e1fSApple OSS Distributions }
44*e3723e1fSApple OSS Distributions
45*e3723e1fSApple OSS Distributions static mach_port_t
alloc_provisional_reply_port()46*e3723e1fSApple OSS Distributions alloc_provisional_reply_port()
47*e3723e1fSApple OSS Distributions {
48*e3723e1fSApple OSS Distributions kern_return_t kr;
49*e3723e1fSApple OSS Distributions mach_port_t reply_port = MACH_PORT_NULL;
50*e3723e1fSApple OSS Distributions mach_port_t task = mach_task_self();
51*e3723e1fSApple OSS Distributions
52*e3723e1fSApple OSS Distributions mach_port_options_t opts = {
53*e3723e1fSApple OSS Distributions .flags = MPO_PROVISIONAL_REPLY_PORT | MPO_INSERT_SEND_RIGHT,
54*e3723e1fSApple OSS Distributions };
55*e3723e1fSApple OSS Distributions
56*e3723e1fSApple OSS Distributions kr = mach_port_construct(mach_task_self(), &opts, 0, &reply_port);
57*e3723e1fSApple OSS Distributions assert(kr == 0);
58*e3723e1fSApple OSS Distributions
59*e3723e1fSApple OSS Distributions return reply_port;
60*e3723e1fSApple OSS Distributions }
61*e3723e1fSApple OSS Distributions
62*e3723e1fSApple OSS Distributions static mach_port_t
alloc_reply_port()63*e3723e1fSApple OSS Distributions alloc_reply_port()
64*e3723e1fSApple OSS Distributions {
65*e3723e1fSApple OSS Distributions kern_return_t kr;
66*e3723e1fSApple OSS Distributions mach_port_t reply_port = MACH_PORT_NULL;
67*e3723e1fSApple OSS Distributions mach_port_t task = mach_task_self();
68*e3723e1fSApple OSS Distributions
69*e3723e1fSApple OSS Distributions mach_port_options_t opts = {
70*e3723e1fSApple OSS Distributions .flags = MPO_REPLY_PORT | MPO_INSERT_SEND_RIGHT,
71*e3723e1fSApple OSS Distributions };
72*e3723e1fSApple OSS Distributions
73*e3723e1fSApple OSS Distributions kr = mach_port_construct(mach_task_self(), &opts, 0, &reply_port);
74*e3723e1fSApple OSS Distributions assert(kr == 0);
75*e3723e1fSApple OSS Distributions
76*e3723e1fSApple OSS Distributions return reply_port;
77*e3723e1fSApple OSS Distributions }
78*e3723e1fSApple OSS Distributions
79*e3723e1fSApple OSS Distributions /* The rcv right of the port would be marked immovable. */
80*e3723e1fSApple OSS Distributions static void
test_immovable_receive_right(void)81*e3723e1fSApple OSS Distributions test_immovable_receive_right(void)
82*e3723e1fSApple OSS Distributions {
83*e3723e1fSApple OSS Distributions kern_return_t kr;
84*e3723e1fSApple OSS Distributions mach_port_t server_port = MACH_PORT_NULL, reply_port = MACH_PORT_NULL;
85*e3723e1fSApple OSS Distributions struct {
86*e3723e1fSApple OSS Distributions mach_msg_header_t header;
87*e3723e1fSApple OSS Distributions mach_msg_body_t body;
88*e3723e1fSApple OSS Distributions mach_msg_port_descriptor_t desc;
89*e3723e1fSApple OSS Distributions } msg;
90*e3723e1fSApple OSS Distributions
91*e3723e1fSApple OSS Distributions server_port = alloc_server_port();
92*e3723e1fSApple OSS Distributions reply_port = alloc_reply_port();
93*e3723e1fSApple OSS Distributions
94*e3723e1fSApple OSS Distributions msg.header.msgh_remote_port = server_port;
95*e3723e1fSApple OSS Distributions msg.header.msgh_local_port = MACH_PORT_NULL;
96*e3723e1fSApple OSS Distributions msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0) | MACH_MSGH_BITS_COMPLEX;
97*e3723e1fSApple OSS Distributions msg.header.msgh_size = sizeof msg;
98*e3723e1fSApple OSS Distributions
99*e3723e1fSApple OSS Distributions msg.body.msgh_descriptor_count = 1;
100*e3723e1fSApple OSS Distributions
101*e3723e1fSApple OSS Distributions msg.desc.name = reply_port;
102*e3723e1fSApple OSS Distributions msg.desc.disposition = MACH_MSG_TYPE_MOVE_RECEIVE;
103*e3723e1fSApple OSS Distributions msg.desc.type = MACH_MSG_PORT_DESCRIPTOR;
104*e3723e1fSApple OSS Distributions kr = mach_msg_send(&msg.header);
105*e3723e1fSApple OSS Distributions
106*e3723e1fSApple OSS Distributions printf("[reply_port_defense_client test_immovable_receive_right]: mach_msg2() returned %d\n", kr);
107*e3723e1fSApple OSS Distributions }
108*e3723e1fSApple OSS Distributions
109*e3723e1fSApple OSS Distributions /* The only way you could create a send once right is when you send the port in local port of a mach msg with MAKE_SEND_ONCE disposition. */
110*e3723e1fSApple OSS Distributions static void
test_make_send_once_right(void)111*e3723e1fSApple OSS Distributions test_make_send_once_right(void)
112*e3723e1fSApple OSS Distributions {
113*e3723e1fSApple OSS Distributions kern_return_t kr;
114*e3723e1fSApple OSS Distributions mach_port_t reply_port = alloc_reply_port();
115*e3723e1fSApple OSS Distributions kr = mach_port_insert_right(mach_task_self(), reply_port, reply_port, MACH_MSG_TYPE_MAKE_SEND_ONCE);
116*e3723e1fSApple OSS Distributions printf("[reply_port_defense_client test_make_send_once_right]: mach_port_insert_right() returned %d\n", kr);
117*e3723e1fSApple OSS Distributions }
118*e3723e1fSApple OSS Distributions
119*e3723e1fSApple OSS Distributions /* The send right of the port would only used for guarding a name in ipc space, it would not allow to send a message. */
120*e3723e1fSApple OSS Distributions static void
test_using_send_right(void)121*e3723e1fSApple OSS Distributions test_using_send_right(void)
122*e3723e1fSApple OSS Distributions {
123*e3723e1fSApple OSS Distributions kern_return_t kr;
124*e3723e1fSApple OSS Distributions mach_port_t reply_port = alloc_reply_port();
125*e3723e1fSApple OSS Distributions struct {
126*e3723e1fSApple OSS Distributions mach_msg_header_t header;
127*e3723e1fSApple OSS Distributions mach_msg_body_t body;
128*e3723e1fSApple OSS Distributions } msg;
129*e3723e1fSApple OSS Distributions
130*e3723e1fSApple OSS Distributions msg.header.msgh_remote_port = reply_port;
131*e3723e1fSApple OSS Distributions msg.header.msgh_local_port = MACH_PORT_NULL;
132*e3723e1fSApple OSS Distributions msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0);
133*e3723e1fSApple OSS Distributions msg.header.msgh_size = sizeof msg;
134*e3723e1fSApple OSS Distributions
135*e3723e1fSApple OSS Distributions kr = mach_msg_send(&msg.header);
136*e3723e1fSApple OSS Distributions printf("[reply_port_defense_client test_using_send_right]: mach_msg2() returned %d\n", kr);
137*e3723e1fSApple OSS Distributions }
138*e3723e1fSApple OSS Distributions
139*e3723e1fSApple OSS Distributions /* The send right of the port would only used for guarding a name in ipc space, it would not allowed to get moved. */
140*e3723e1fSApple OSS Distributions static void
test_move_send_right(void)141*e3723e1fSApple OSS Distributions test_move_send_right(void)
142*e3723e1fSApple OSS Distributions {
143*e3723e1fSApple OSS Distributions kern_return_t kr;
144*e3723e1fSApple OSS Distributions mach_port_t server_port = MACH_PORT_NULL, reply_port = MACH_PORT_NULL;
145*e3723e1fSApple OSS Distributions struct {
146*e3723e1fSApple OSS Distributions mach_msg_header_t header;
147*e3723e1fSApple OSS Distributions mach_msg_body_t body;
148*e3723e1fSApple OSS Distributions mach_msg_port_descriptor_t desc;
149*e3723e1fSApple OSS Distributions } msg;
150*e3723e1fSApple OSS Distributions
151*e3723e1fSApple OSS Distributions server_port = alloc_server_port();
152*e3723e1fSApple OSS Distributions reply_port = alloc_reply_port();
153*e3723e1fSApple OSS Distributions
154*e3723e1fSApple OSS Distributions msg.header.msgh_remote_port = server_port;
155*e3723e1fSApple OSS Distributions msg.header.msgh_local_port = MACH_PORT_NULL;
156*e3723e1fSApple OSS Distributions msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0) | MACH_MSGH_BITS_COMPLEX;
157*e3723e1fSApple OSS Distributions msg.header.msgh_size = sizeof msg;
158*e3723e1fSApple OSS Distributions
159*e3723e1fSApple OSS Distributions msg.body.msgh_descriptor_count = 1;
160*e3723e1fSApple OSS Distributions
161*e3723e1fSApple OSS Distributions msg.desc.name = reply_port;
162*e3723e1fSApple OSS Distributions msg.desc.disposition = MACH_MSG_TYPE_MOVE_SEND;
163*e3723e1fSApple OSS Distributions msg.desc.type = MACH_MSG_PORT_DESCRIPTOR;
164*e3723e1fSApple OSS Distributions
165*e3723e1fSApple OSS Distributions kr = mach_msg_send(&msg.header);
166*e3723e1fSApple OSS Distributions printf("[reply_port_defense_client test_move_send_right]: mach_msg2() returned %d\n", kr);
167*e3723e1fSApple OSS Distributions }
168*e3723e1fSApple OSS Distributions
169*e3723e1fSApple OSS Distributions static void
test_move_provisional_reply_port(void)170*e3723e1fSApple OSS Distributions test_move_provisional_reply_port(void)
171*e3723e1fSApple OSS Distributions {
172*e3723e1fSApple OSS Distributions kern_return_t kr;
173*e3723e1fSApple OSS Distributions mach_port_t server_port = MACH_PORT_NULL, reply_port = MACH_PORT_NULL;
174*e3723e1fSApple OSS Distributions struct {
175*e3723e1fSApple OSS Distributions mach_msg_header_t header;
176*e3723e1fSApple OSS Distributions mach_msg_body_t body;
177*e3723e1fSApple OSS Distributions mach_msg_port_descriptor_t desc;
178*e3723e1fSApple OSS Distributions } msg;
179*e3723e1fSApple OSS Distributions
180*e3723e1fSApple OSS Distributions server_port = alloc_server_port();
181*e3723e1fSApple OSS Distributions reply_port = alloc_provisional_reply_port();
182*e3723e1fSApple OSS Distributions
183*e3723e1fSApple OSS Distributions msg.header.msgh_remote_port = server_port;
184*e3723e1fSApple OSS Distributions msg.header.msgh_local_port = MACH_PORT_NULL;
185*e3723e1fSApple OSS Distributions msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0) | MACH_MSGH_BITS_COMPLEX;
186*e3723e1fSApple OSS Distributions msg.header.msgh_size = sizeof msg;
187*e3723e1fSApple OSS Distributions
188*e3723e1fSApple OSS Distributions msg.body.msgh_descriptor_count = 1;
189*e3723e1fSApple OSS Distributions
190*e3723e1fSApple OSS Distributions msg.desc.name = reply_port;
191*e3723e1fSApple OSS Distributions msg.desc.disposition = MACH_MSG_TYPE_MOVE_RECEIVE;
192*e3723e1fSApple OSS Distributions msg.desc.type = MACH_MSG_PORT_DESCRIPTOR;
193*e3723e1fSApple OSS Distributions
194*e3723e1fSApple OSS Distributions kr = mach_msg_send(&msg.header);
195*e3723e1fSApple OSS Distributions
196*e3723e1fSApple OSS Distributions printf("[reply_port_defense_client test_immovable_receive_right]: mach_msg2() returned %d\n", kr);
197*e3723e1fSApple OSS Distributions }
198*e3723e1fSApple OSS Distributions
199*e3723e1fSApple OSS Distributions static void
test_unentitled_thread_set_state(void)200*e3723e1fSApple OSS Distributions test_unentitled_thread_set_state(void)
201*e3723e1fSApple OSS Distributions {
202*e3723e1fSApple OSS Distributions machine_thread_state_t ts;
203*e3723e1fSApple OSS Distributions mach_msg_type_number_t count = MACHINE_THREAD_STATE_COUNT;
204*e3723e1fSApple OSS Distributions
205*e3723e1fSApple OSS Distributions /* thread_set_state as a hardened binary should fail */
206*e3723e1fSApple OSS Distributions kern_return_t kr = thread_get_state(mach_thread_self(), MACHINE_THREAD_STATE, (thread_state_t)&ts, &count);
207*e3723e1fSApple OSS Distributions
208*e3723e1fSApple OSS Distributions kr = thread_set_state(mach_thread_self(), MACHINE_THREAD_STATE, (thread_state_t)&ts, count);
209*e3723e1fSApple OSS Distributions assert(kr != KERN_SUCCESS);
210*e3723e1fSApple OSS Distributions exit(-1); /* Should have crashed before here! */
211*e3723e1fSApple OSS Distributions }
212*e3723e1fSApple OSS Distributions
213*e3723e1fSApple OSS Distributions static void
unentitled_set_exception_ports_crash(void)214*e3723e1fSApple OSS Distributions unentitled_set_exception_ports_crash(void)
215*e3723e1fSApple OSS Distributions {
216*e3723e1fSApple OSS Distributions mach_port_t exc_port = alloc_server_port();
217*e3723e1fSApple OSS Distributions
218*e3723e1fSApple OSS Distributions /* thread_set_exception_ports as a hardened binary should fail */
219*e3723e1fSApple OSS Distributions kern_return_t kr = thread_set_exception_ports(
220*e3723e1fSApple OSS Distributions mach_thread_self(),
221*e3723e1fSApple OSS Distributions EXC_MASK_ALL,
222*e3723e1fSApple OSS Distributions exc_port,
223*e3723e1fSApple OSS Distributions (exception_behavior_t)((unsigned int)EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES),
224*e3723e1fSApple OSS Distributions EXCEPTION_THREAD_STATE);
225*e3723e1fSApple OSS Distributions
226*e3723e1fSApple OSS Distributions /* thread_set_exception_ports is supposed to crash, unless the policy is turned off.
227*e3723e1fSApple OSS Distributions * Things that disable the policy: AMFI boot-args in use, SIP disabled,
228*e3723e1fSApple OSS Distributions * third party plugins in a process. The caller of this client will check
229*e3723e1fSApple OSS Distributions * whether the test crashed and correctly adhered to these policies.
230*e3723e1fSApple OSS Distributions */
231*e3723e1fSApple OSS Distributions printf("thread_set_exception_ports did not crash\n");
232*e3723e1fSApple OSS Distributions }
233*e3723e1fSApple OSS Distributions
234*e3723e1fSApple OSS Distributions static void
unentitled_set_exception_ports_pass(void)235*e3723e1fSApple OSS Distributions unentitled_set_exception_ports_pass(void)
236*e3723e1fSApple OSS Distributions {
237*e3723e1fSApple OSS Distributions mach_port_t exc_port = alloc_server_port();
238*e3723e1fSApple OSS Distributions
239*e3723e1fSApple OSS Distributions /* thread_set_exception_ports with state *IDENTITY_PROTECTED should not fail */
240*e3723e1fSApple OSS Distributions kern_return_t kr = thread_set_exception_ports(
241*e3723e1fSApple OSS Distributions mach_thread_self(),
242*e3723e1fSApple OSS Distributions EXC_MASK_ALL,
243*e3723e1fSApple OSS Distributions exc_port,
244*e3723e1fSApple OSS Distributions (exception_behavior_t)((unsigned int)EXCEPTION_STATE_IDENTITY_PROTECTED | MACH_EXCEPTION_CODES),
245*e3723e1fSApple OSS Distributions EXCEPTION_THREAD_STATE);
246*e3723e1fSApple OSS Distributions assert(kr == 0);
247*e3723e1fSApple OSS Distributions
248*e3723e1fSApple OSS Distributions kr = thread_set_exception_ports(
249*e3723e1fSApple OSS Distributions mach_thread_self(),
250*e3723e1fSApple OSS Distributions EXC_MASK_ALL,
251*e3723e1fSApple OSS Distributions exc_port,
252*e3723e1fSApple OSS Distributions (exception_behavior_t)((unsigned int)EXCEPTION_IDENTITY_PROTECTED | MACH_EXCEPTION_CODES),
253*e3723e1fSApple OSS Distributions EXCEPTION_THREAD_STATE);
254*e3723e1fSApple OSS Distributions assert(kr == 0);
255*e3723e1fSApple OSS Distributions
256*e3723e1fSApple OSS Distributions return;
257*e3723e1fSApple OSS Distributions }
258*e3723e1fSApple OSS Distributions
259*e3723e1fSApple OSS Distributions static void
exception_ports_crash(void)260*e3723e1fSApple OSS Distributions exception_ports_crash(void)
261*e3723e1fSApple OSS Distributions {
262*e3723e1fSApple OSS Distributions kern_return_t kr;
263*e3723e1fSApple OSS Distributions mach_port_t exc_port;
264*e3723e1fSApple OSS Distributions mach_port_options_t opts = {
265*e3723e1fSApple OSS Distributions .flags = MPO_INSERT_SEND_RIGHT | MPO_EXCEPTION_PORT,
266*e3723e1fSApple OSS Distributions };
267*e3723e1fSApple OSS Distributions
268*e3723e1fSApple OSS Distributions kr = mach_port_construct(mach_task_self(), &opts, 0ull, &exc_port);
269*e3723e1fSApple OSS Distributions assert(kr == KERN_SUCCESS);
270*e3723e1fSApple OSS Distributions
271*e3723e1fSApple OSS Distributions kr = task_register_hardened_exception_handler(current_task(),
272*e3723e1fSApple OSS Distributions 0, EXC_MASK_BAD_ACCESS,
273*e3723e1fSApple OSS Distributions EXCEPTION_STATE_IDENTITY_PROTECTED, EXCEPTION_THREAD_STATE, exc_port);
274*e3723e1fSApple OSS Distributions
275*e3723e1fSApple OSS Distributions kr = thread_set_exception_ports(
276*e3723e1fSApple OSS Distributions mach_thread_self(),
277*e3723e1fSApple OSS Distributions EXC_MASK_BAD_ACCESS,
278*e3723e1fSApple OSS Distributions exc_port,
279*e3723e1fSApple OSS Distributions (exception_behavior_t)((unsigned int)EXCEPTION_STATE_IDENTITY_PROTECTED | MACH_EXCEPTION_CODES),
280*e3723e1fSApple OSS Distributions EXCEPTION_THREAD_STATE);
281*e3723e1fSApple OSS Distributions
282*e3723e1fSApple OSS Distributions printf("thread_set_exception_ports did not crash: %d\n", kr);
283*e3723e1fSApple OSS Distributions }
284*e3723e1fSApple OSS Distributions
285*e3723e1fSApple OSS Distributions static void
kobject_reply_port_defense(void)286*e3723e1fSApple OSS Distributions kobject_reply_port_defense(void)
287*e3723e1fSApple OSS Distributions {
288*e3723e1fSApple OSS Distributions machine_thread_state_t ts;
289*e3723e1fSApple OSS Distributions mach_msg_type_number_t count = MACHINE_THREAD_STATE_COUNT;
290*e3723e1fSApple OSS Distributions mach_port_t port = MACH_PORT_NULL;
291*e3723e1fSApple OSS Distributions
292*e3723e1fSApple OSS Distributions kern_return_t kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port);
293*e3723e1fSApple OSS Distributions assert(kr == KERN_SUCCESS);
294*e3723e1fSApple OSS Distributions
295*e3723e1fSApple OSS Distributions // make a kobject call
296*e3723e1fSApple OSS Distributions kr = thread_get_state(mach_thread_self(), MACHINE_THREAD_STATE, (thread_state_t)&ts, &count);
297*e3723e1fSApple OSS Distributions assert(kr == KERN_SUCCESS);
298*e3723e1fSApple OSS Distributions
299*e3723e1fSApple OSS Distributions // set the MIG reply port to a "normal" port
300*e3723e1fSApple OSS Distributions _os_tsd_set_direct(__TSD_MIG_REPLY, (void *)(uintptr_t)port);
301*e3723e1fSApple OSS Distributions
302*e3723e1fSApple OSS Distributions kr = thread_get_state(mach_thread_self(), MACHINE_THREAD_STATE, (thread_state_t)&ts, &count);
303*e3723e1fSApple OSS Distributions
304*e3723e1fSApple OSS Distributions printf("kobject call did not crash: %d\n", kr);
305*e3723e1fSApple OSS Distributions }
306*e3723e1fSApple OSS Distributions
307*e3723e1fSApple OSS Distributions static void
test_alloc_provisional_reply_port(void)308*e3723e1fSApple OSS Distributions test_alloc_provisional_reply_port(void)
309*e3723e1fSApple OSS Distributions {
310*e3723e1fSApple OSS Distributions mach_port_t __unused reply_port = alloc_provisional_reply_port();
311*e3723e1fSApple OSS Distributions }
312*e3723e1fSApple OSS Distributions
313*e3723e1fSApple OSS Distributions int
main(int argc,char * argv[])314*e3723e1fSApple OSS Distributions main(int argc, char *argv[])
315*e3723e1fSApple OSS Distributions {
316*e3723e1fSApple OSS Distributions uint32_t my_csflags = 0;
317*e3723e1fSApple OSS Distributions bool thirdparty_hardened = !strcmp(argv[0], "./reply_port_defense_client_3P_hardened");
318*e3723e1fSApple OSS Distributions
319*e3723e1fSApple OSS Distributions /* TODO add some sysctl which disabled platform binary bit here */
320*e3723e1fSApple OSS Distributions if (my_csflags & CS_PLATFORM_BINARY == thirdparty_hardened) {
321*e3723e1fSApple OSS Distributions printf("platform binary does not match expected\n");
322*e3723e1fSApple OSS Distributions return -1;
323*e3723e1fSApple OSS Distributions }
324*e3723e1fSApple OSS Distributions
325*e3723e1fSApple OSS Distributions
326*e3723e1fSApple OSS Distributions void (*tests[MAX_TEST_NUM])(void) = {
327*e3723e1fSApple OSS Distributions test_immovable_receive_right, /* 0 */
328*e3723e1fSApple OSS Distributions test_make_send_once_right,
329*e3723e1fSApple OSS Distributions test_using_send_right, /* 2 */
330*e3723e1fSApple OSS Distributions test_move_send_right,
331*e3723e1fSApple OSS Distributions test_move_provisional_reply_port, /* 4 */
332*e3723e1fSApple OSS Distributions unentitled_set_exception_ports_crash,
333*e3723e1fSApple OSS Distributions test_unentitled_thread_set_state, /* 6 */
334*e3723e1fSApple OSS Distributions unentitled_set_exception_ports_pass,
335*e3723e1fSApple OSS Distributions exception_ports_crash, /* 8 */
336*e3723e1fSApple OSS Distributions kobject_reply_port_defense, /* 9 */
337*e3723e1fSApple OSS Distributions test_alloc_provisional_reply_port, /* 10 */
338*e3723e1fSApple OSS Distributions };
339*e3723e1fSApple OSS Distributions
340*e3723e1fSApple OSS Distributions if (argc < 2) {
341*e3723e1fSApple OSS Distributions printf("[reply_port_defense_client]: Specify a test to run.");
342*e3723e1fSApple OSS Distributions exit(-1);
343*e3723e1fSApple OSS Distributions }
344*e3723e1fSApple OSS Distributions
345*e3723e1fSApple OSS Distributions int test_num = atoi(argv[1]);
346*e3723e1fSApple OSS Distributions printf("[reply_port_defense_client]: My Pid: %d Test num: %d third_party_hardened: %s\n",
347*e3723e1fSApple OSS Distributions getpid(), test_num, thirdparty_hardened ? "yes" : "no");
348*e3723e1fSApple OSS Distributions fflush(stdout);
349*e3723e1fSApple OSS Distributions if (test_num >= 0 && test_num < MAX_TEST_NUM) {
350*e3723e1fSApple OSS Distributions (*tests[test_num])();
351*e3723e1fSApple OSS Distributions } else {
352*e3723e1fSApple OSS Distributions printf("[reply_port_defense_client]: Invalid test num. Exiting...\n");
353*e3723e1fSApple OSS Distributions exit(-1);
354*e3723e1fSApple OSS Distributions }
355*e3723e1fSApple OSS Distributions printf("Child exiting cleanly!!\n");
356*e3723e1fSApple OSS Distributions fflush(stdout);
357*e3723e1fSApple OSS Distributions // return 0;
358*e3723e1fSApple OSS Distributions exit(0);
359*e3723e1fSApple OSS Distributions }
360