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