1*19c3b8c2SApple OSS Distributions #include <darwintest.h>
2*19c3b8c2SApple OSS Distributions
3*19c3b8c2SApple OSS Distributions #include <pthread.h>
4*19c3b8c2SApple OSS Distributions #include <setjmp.h>
5*19c3b8c2SApple OSS Distributions #include <signal.h>
6*19c3b8c2SApple OSS Distributions #include <stdlib.h>
7*19c3b8c2SApple OSS Distributions #include <unistd.h>
8*19c3b8c2SApple OSS Distributions #include <mach/mach.h>
9*19c3b8c2SApple OSS Distributions #include <pthread/qos_private.h>
10*19c3b8c2SApple OSS Distributions #include <mach/mach_voucher.h>
11*19c3b8c2SApple OSS Distributions #include <bank/bank_types.h>
12*19c3b8c2SApple OSS Distributions
13*19c3b8c2SApple OSS Distributions T_GLOBAL_META(T_META_RUN_CONCURRENTLY(true),
14*19c3b8c2SApple OSS Distributions T_META_NAMESPACE("xnu.ipc"),
15*19c3b8c2SApple OSS Distributions T_META_RADAR_COMPONENT_NAME("xnu"),
16*19c3b8c2SApple OSS Distributions T_META_RADAR_COMPONENT_VERSION("IPC"));
17*19c3b8c2SApple OSS Distributions
18*19c3b8c2SApple OSS Distributions #define MSG 1024
19*19c3b8c2SApple OSS Distributions #define PG_ALLOC 4096
20*19c3b8c2SApple OSS Distributions
21*19c3b8c2SApple OSS Distributions typedef enum {
22*19c3b8c2SApple OSS Distributions ReplyWithNoError,
23*19c3b8c2SApple OSS Distributions ReplyWithReplyPort,
24*19c3b8c2SApple OSS Distributions ReplyWithReplyPortMove,
25*19c3b8c2SApple OSS Distributions ReplyWithReplyPortCplxBit,
26*19c3b8c2SApple OSS Distributions ReplyWithReplyPortMoveCplxBit,
27*19c3b8c2SApple OSS Distributions ReplyWithPortDesc,
28*19c3b8c2SApple OSS Distributions ReplyWithOOLDesc,
29*19c3b8c2SApple OSS Distributions ReplyWithVoucher,
30*19c3b8c2SApple OSS Distributions ReplyWithVoucherGarbage
31*19c3b8c2SApple OSS Distributions } ReplyType;
32*19c3b8c2SApple OSS Distributions
33*19c3b8c2SApple OSS Distributions struct exc_thread_arg {
34*19c3b8c2SApple OSS Distributions ReplyType rt;
35*19c3b8c2SApple OSS Distributions mach_port_t port;
36*19c3b8c2SApple OSS Distributions };
37*19c3b8c2SApple OSS Distributions
38*19c3b8c2SApple OSS Distributions static const char *
reply_type_str(ReplyType rt)39*19c3b8c2SApple OSS Distributions reply_type_str(ReplyType rt)
40*19c3b8c2SApple OSS Distributions {
41*19c3b8c2SApple OSS Distributions switch (rt) {
42*19c3b8c2SApple OSS Distributions case ReplyWithNoError:
43*19c3b8c2SApple OSS Distributions return "ReplyWithNoError";
44*19c3b8c2SApple OSS Distributions case ReplyWithReplyPort:
45*19c3b8c2SApple OSS Distributions return "ReplyWithReplyPort";
46*19c3b8c2SApple OSS Distributions case ReplyWithReplyPortMove:
47*19c3b8c2SApple OSS Distributions return "ReplyWithReplyPortMove";
48*19c3b8c2SApple OSS Distributions case ReplyWithReplyPortCplxBit:
49*19c3b8c2SApple OSS Distributions return "ReplyWithReplyPortCplxBit";
50*19c3b8c2SApple OSS Distributions case ReplyWithReplyPortMoveCplxBit:
51*19c3b8c2SApple OSS Distributions return "ReplyWithReplyPortMoveCplxBit";
52*19c3b8c2SApple OSS Distributions case ReplyWithPortDesc:
53*19c3b8c2SApple OSS Distributions return "ReplyWithPortDesc";
54*19c3b8c2SApple OSS Distributions case ReplyWithOOLDesc:
55*19c3b8c2SApple OSS Distributions return "ReplyWithOOLDesc";
56*19c3b8c2SApple OSS Distributions case ReplyWithVoucher:
57*19c3b8c2SApple OSS Distributions return "ReplyWithVoucher";
58*19c3b8c2SApple OSS Distributions case ReplyWithVoucherGarbage:
59*19c3b8c2SApple OSS Distributions return "ReplyWithVoucherGarbage";
60*19c3b8c2SApple OSS Distributions }
61*19c3b8c2SApple OSS Distributions }
62*19c3b8c2SApple OSS Distributions
63*19c3b8c2SApple OSS Distributions static mach_voucher_t
create_task_voucher(void)64*19c3b8c2SApple OSS Distributions create_task_voucher(void)
65*19c3b8c2SApple OSS Distributions {
66*19c3b8c2SApple OSS Distributions static mach_voucher_attr_recipe_data_t task_create_recipe = {
67*19c3b8c2SApple OSS Distributions .key = MACH_VOUCHER_ATTR_KEY_BANK,
68*19c3b8c2SApple OSS Distributions .command = MACH_VOUCHER_ATTR_BANK_CREATE,
69*19c3b8c2SApple OSS Distributions };
70*19c3b8c2SApple OSS Distributions mach_voucher_t voucher = MACH_PORT_NULL;
71*19c3b8c2SApple OSS Distributions kern_return_t kr;
72*19c3b8c2SApple OSS Distributions
73*19c3b8c2SApple OSS Distributions kr = host_create_mach_voucher(mach_host_self(),
74*19c3b8c2SApple OSS Distributions (mach_voucher_attr_raw_recipe_array_t)&task_create_recipe,
75*19c3b8c2SApple OSS Distributions sizeof(task_create_recipe),
76*19c3b8c2SApple OSS Distributions &voucher);
77*19c3b8c2SApple OSS Distributions
78*19c3b8c2SApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "host_create_mach_voucher");
79*19c3b8c2SApple OSS Distributions return voucher;
80*19c3b8c2SApple OSS Distributions }
81*19c3b8c2SApple OSS Distributions
82*19c3b8c2SApple OSS Distributions static void *
handle_exceptions(void * arg)83*19c3b8c2SApple OSS Distributions handle_exceptions(void *arg)
84*19c3b8c2SApple OSS Distributions {
85*19c3b8c2SApple OSS Distributions struct exc_thread_arg *ta = (struct exc_thread_arg *)arg;
86*19c3b8c2SApple OSS Distributions mach_port_t ePort = ta->port;
87*19c3b8c2SApple OSS Distributions ReplyType reply_type = ta->rt;
88*19c3b8c2SApple OSS Distributions
89*19c3b8c2SApple OSS Distributions char msg_store[MSG + MAX_TRAILER_SIZE];
90*19c3b8c2SApple OSS Distributions char reply_store[MSG];
91*19c3b8c2SApple OSS Distributions mach_msg_header_t *msg = (mach_msg_header_t *)msg_store;
92*19c3b8c2SApple OSS Distributions vm_address_t page;
93*19c3b8c2SApple OSS Distributions kern_return_t kr;
94*19c3b8c2SApple OSS Distributions
95*19c3b8c2SApple OSS Distributions kr = vm_allocate(mach_task_self(), &page, PG_ALLOC, VM_FLAGS_ANYWHERE);
96*19c3b8c2SApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "ool page allocation of %d bytes", PG_ALLOC);
97*19c3b8c2SApple OSS Distributions
98*19c3b8c2SApple OSS Distributions mach_voucher_t voucher = create_task_voucher();
99*19c3b8c2SApple OSS Distributions
100*19c3b8c2SApple OSS Distributions while (1) {
101*19c3b8c2SApple OSS Distributions bzero(msg, sizeof(msg_store));
102*19c3b8c2SApple OSS Distributions
103*19c3b8c2SApple OSS Distributions msg->msgh_local_port = ePort;
104*19c3b8c2SApple OSS Distributions msg->msgh_size = MSG;
105*19c3b8c2SApple OSS Distributions kr = mach_msg_receive(msg);
106*19c3b8c2SApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "exception msg recv");
107*19c3b8c2SApple OSS Distributions
108*19c3b8c2SApple OSS Distributions bzero(reply_store, sizeof(reply_store));
109*19c3b8c2SApple OSS Distributions
110*19c3b8c2SApple OSS Distributions switch (reply_type) {
111*19c3b8c2SApple OSS Distributions case ReplyWithNoError: {
112*19c3b8c2SApple OSS Distributions #pragma pack(4)
113*19c3b8c2SApple OSS Distributions typedef struct {
114*19c3b8c2SApple OSS Distributions mach_msg_header_t hdr;
115*19c3b8c2SApple OSS Distributions NDR_record_t ndr;
116*19c3b8c2SApple OSS Distributions kern_return_t kr;
117*19c3b8c2SApple OSS Distributions } reply_fmt_t;
118*19c3b8c2SApple OSS Distributions #pragma pack()
119*19c3b8c2SApple OSS Distributions reply_fmt_t *reply = (reply_fmt_t *)reply_store;
120*19c3b8c2SApple OSS Distributions
121*19c3b8c2SApple OSS Distributions reply->hdr.msgh_bits = MACH_MSGH_BITS_SET(MACH_MSG_TYPE_MOVE_SEND_ONCE, 0, 0, 0);
122*19c3b8c2SApple OSS Distributions reply->hdr.msgh_remote_port = msg->msgh_remote_port;
123*19c3b8c2SApple OSS Distributions reply->hdr.msgh_local_port = MACH_PORT_NULL;
124*19c3b8c2SApple OSS Distributions reply->hdr.msgh_size = sizeof(*reply);
125*19c3b8c2SApple OSS Distributions reply->hdr.msgh_id = msg->msgh_id + 100;
126*19c3b8c2SApple OSS Distributions break;
127*19c3b8c2SApple OSS Distributions }
128*19c3b8c2SApple OSS Distributions
129*19c3b8c2SApple OSS Distributions case ReplyWithReplyPort: {
130*19c3b8c2SApple OSS Distributions #pragma pack(4)
131*19c3b8c2SApple OSS Distributions typedef struct {
132*19c3b8c2SApple OSS Distributions mach_msg_header_t hdr;
133*19c3b8c2SApple OSS Distributions NDR_record_t ndr;
134*19c3b8c2SApple OSS Distributions kern_return_t kr;
135*19c3b8c2SApple OSS Distributions } reply_fmt_t;
136*19c3b8c2SApple OSS Distributions #pragma pack()
137*19c3b8c2SApple OSS Distributions reply_fmt_t *reply = (reply_fmt_t *)reply_store;
138*19c3b8c2SApple OSS Distributions
139*19c3b8c2SApple OSS Distributions reply->hdr.msgh_bits = MACH_MSGH_BITS_SET(MACH_MSG_TYPE_MOVE_SEND_ONCE, MACH_MSG_TYPE_COPY_SEND, 0, 0);
140*19c3b8c2SApple OSS Distributions reply->hdr.msgh_remote_port = msg->msgh_remote_port;
141*19c3b8c2SApple OSS Distributions reply->hdr.msgh_local_port = ePort; /* Bogus */
142*19c3b8c2SApple OSS Distributions reply->hdr.msgh_size = sizeof(*reply);
143*19c3b8c2SApple OSS Distributions reply->hdr.msgh_id = msg->msgh_id + 100;
144*19c3b8c2SApple OSS Distributions break;
145*19c3b8c2SApple OSS Distributions }
146*19c3b8c2SApple OSS Distributions
147*19c3b8c2SApple OSS Distributions case ReplyWithReplyPortMove: {
148*19c3b8c2SApple OSS Distributions #pragma pack(4)
149*19c3b8c2SApple OSS Distributions typedef struct {
150*19c3b8c2SApple OSS Distributions mach_msg_header_t hdr;
151*19c3b8c2SApple OSS Distributions NDR_record_t ndr;
152*19c3b8c2SApple OSS Distributions kern_return_t kr;
153*19c3b8c2SApple OSS Distributions } reply_fmt_t;
154*19c3b8c2SApple OSS Distributions #pragma pack()
155*19c3b8c2SApple OSS Distributions reply_fmt_t *reply = (reply_fmt_t *)reply_store;
156*19c3b8c2SApple OSS Distributions
157*19c3b8c2SApple OSS Distributions reply->hdr.msgh_bits = MACH_MSGH_BITS_SET(MACH_MSG_TYPE_MOVE_SEND_ONCE, MACH_MSG_TYPE_MOVE_SEND, 0, 0);
158*19c3b8c2SApple OSS Distributions reply->hdr.msgh_remote_port = msg->msgh_remote_port;
159*19c3b8c2SApple OSS Distributions reply->hdr.msgh_local_port = ePort; /* Bogus */
160*19c3b8c2SApple OSS Distributions reply->hdr.msgh_size = sizeof(*reply);
161*19c3b8c2SApple OSS Distributions reply->hdr.msgh_id = msg->msgh_id + 100;
162*19c3b8c2SApple OSS Distributions break;
163*19c3b8c2SApple OSS Distributions }
164*19c3b8c2SApple OSS Distributions
165*19c3b8c2SApple OSS Distributions case ReplyWithReplyPortCplxBit: {
166*19c3b8c2SApple OSS Distributions #pragma pack(4)
167*19c3b8c2SApple OSS Distributions typedef struct {
168*19c3b8c2SApple OSS Distributions mach_msg_header_t hdr;
169*19c3b8c2SApple OSS Distributions mach_msg_body_t body;
170*19c3b8c2SApple OSS Distributions } reply_fmt_t;
171*19c3b8c2SApple OSS Distributions #pragma pack()
172*19c3b8c2SApple OSS Distributions reply_fmt_t *reply = (reply_fmt_t *)reply_store;
173*19c3b8c2SApple OSS Distributions
174*19c3b8c2SApple OSS Distributions reply->hdr.msgh_bits = MACH_MSGH_BITS_SET(MACH_MSG_TYPE_MOVE_SEND_ONCE, MACH_MSG_TYPE_COPY_SEND, 0, MACH_MSGH_BITS_COMPLEX);
175*19c3b8c2SApple OSS Distributions reply->hdr.msgh_remote_port = msg->msgh_remote_port;
176*19c3b8c2SApple OSS Distributions reply->hdr.msgh_local_port = ePort; /* Bogus */
177*19c3b8c2SApple OSS Distributions reply->hdr.msgh_size = sizeof(*reply);
178*19c3b8c2SApple OSS Distributions reply->hdr.msgh_id = msg->msgh_id + 100;
179*19c3b8c2SApple OSS Distributions reply->body.msgh_descriptor_count = 0;
180*19c3b8c2SApple OSS Distributions break;
181*19c3b8c2SApple OSS Distributions }
182*19c3b8c2SApple OSS Distributions
183*19c3b8c2SApple OSS Distributions case ReplyWithReplyPortMoveCplxBit: {
184*19c3b8c2SApple OSS Distributions #pragma pack(4)
185*19c3b8c2SApple OSS Distributions typedef struct {
186*19c3b8c2SApple OSS Distributions mach_msg_header_t hdr;
187*19c3b8c2SApple OSS Distributions mach_msg_body_t body;
188*19c3b8c2SApple OSS Distributions } reply_fmt_t;
189*19c3b8c2SApple OSS Distributions #pragma pack()
190*19c3b8c2SApple OSS Distributions reply_fmt_t *reply = (reply_fmt_t *)reply_store;
191*19c3b8c2SApple OSS Distributions
192*19c3b8c2SApple OSS Distributions reply->hdr.msgh_bits = MACH_MSGH_BITS_SET(MACH_MSG_TYPE_MOVE_SEND_ONCE, MACH_MSG_TYPE_MOVE_SEND, 0, MACH_MSGH_BITS_COMPLEX);
193*19c3b8c2SApple OSS Distributions reply->hdr.msgh_remote_port = msg->msgh_remote_port;
194*19c3b8c2SApple OSS Distributions reply->hdr.msgh_local_port = ePort; /* Bogus */
195*19c3b8c2SApple OSS Distributions reply->hdr.msgh_size = sizeof(*reply);
196*19c3b8c2SApple OSS Distributions reply->hdr.msgh_id = msg->msgh_id + 100;
197*19c3b8c2SApple OSS Distributions reply->body.msgh_descriptor_count = 0;
198*19c3b8c2SApple OSS Distributions break;
199*19c3b8c2SApple OSS Distributions }
200*19c3b8c2SApple OSS Distributions
201*19c3b8c2SApple OSS Distributions case ReplyWithPortDesc: {
202*19c3b8c2SApple OSS Distributions #pragma pack(4)
203*19c3b8c2SApple OSS Distributions typedef struct {
204*19c3b8c2SApple OSS Distributions mach_msg_header_t hdr;
205*19c3b8c2SApple OSS Distributions mach_msg_body_t body;
206*19c3b8c2SApple OSS Distributions mach_msg_port_descriptor_t port;
207*19c3b8c2SApple OSS Distributions } reply_fmt_t;
208*19c3b8c2SApple OSS Distributions #pragma pack()
209*19c3b8c2SApple OSS Distributions reply_fmt_t *reply = (reply_fmt_t *)reply_store;
210*19c3b8c2SApple OSS Distributions
211*19c3b8c2SApple OSS Distributions reply->hdr.msgh_bits = MACH_MSGH_BITS_SET(MACH_MSG_TYPE_MOVE_SEND_ONCE, 0, 0, MACH_MSGH_BITS_COMPLEX);
212*19c3b8c2SApple OSS Distributions reply->hdr.msgh_remote_port = msg->msgh_remote_port;
213*19c3b8c2SApple OSS Distributions reply->hdr.msgh_local_port = MACH_PORT_NULL;
214*19c3b8c2SApple OSS Distributions reply->hdr.msgh_size = sizeof(*reply);
215*19c3b8c2SApple OSS Distributions reply->hdr.msgh_id = msg->msgh_id + 100;
216*19c3b8c2SApple OSS Distributions reply->body.msgh_descriptor_count = 1;
217*19c3b8c2SApple OSS Distributions reply->port.type = MACH_MSG_PORT_DESCRIPTOR;
218*19c3b8c2SApple OSS Distributions reply->port.name = ePort;
219*19c3b8c2SApple OSS Distributions reply->port.disposition = MACH_MSG_TYPE_COPY_SEND;
220*19c3b8c2SApple OSS Distributions break;
221*19c3b8c2SApple OSS Distributions }
222*19c3b8c2SApple OSS Distributions
223*19c3b8c2SApple OSS Distributions case ReplyWithOOLDesc: {
224*19c3b8c2SApple OSS Distributions #pragma pack(4)
225*19c3b8c2SApple OSS Distributions typedef struct {
226*19c3b8c2SApple OSS Distributions mach_msg_header_t hdr;
227*19c3b8c2SApple OSS Distributions mach_msg_body_t body;
228*19c3b8c2SApple OSS Distributions mach_msg_ool_descriptor_t ool;
229*19c3b8c2SApple OSS Distributions } reply_fmt_t;
230*19c3b8c2SApple OSS Distributions #pragma pack()
231*19c3b8c2SApple OSS Distributions reply_fmt_t *reply = (reply_fmt_t *)reply_store;
232*19c3b8c2SApple OSS Distributions
233*19c3b8c2SApple OSS Distributions reply->hdr.msgh_bits = MACH_MSGH_BITS_SET(MACH_MSG_TYPE_MOVE_SEND_ONCE, 0, 0, MACH_MSGH_BITS_COMPLEX);
234*19c3b8c2SApple OSS Distributions reply->hdr.msgh_remote_port = msg->msgh_remote_port;
235*19c3b8c2SApple OSS Distributions reply->hdr.msgh_local_port = MACH_PORT_NULL;
236*19c3b8c2SApple OSS Distributions reply->hdr.msgh_size = sizeof(*reply);
237*19c3b8c2SApple OSS Distributions reply->hdr.msgh_id = msg->msgh_id + 100;
238*19c3b8c2SApple OSS Distributions reply->body.msgh_descriptor_count = 1;
239*19c3b8c2SApple OSS Distributions reply->ool.type = MACH_MSG_OOL_DESCRIPTOR;
240*19c3b8c2SApple OSS Distributions reply->ool.address = (void *)page;
241*19c3b8c2SApple OSS Distributions reply->ool.size = PG_ALLOC;
242*19c3b8c2SApple OSS Distributions reply->ool.deallocate = 0;
243*19c3b8c2SApple OSS Distributions reply->ool.copy = MACH_MSG_VIRTUAL_COPY;
244*19c3b8c2SApple OSS Distributions break;
245*19c3b8c2SApple OSS Distributions }
246*19c3b8c2SApple OSS Distributions
247*19c3b8c2SApple OSS Distributions case ReplyWithVoucher: {
248*19c3b8c2SApple OSS Distributions #pragma pack(4)
249*19c3b8c2SApple OSS Distributions typedef struct {
250*19c3b8c2SApple OSS Distributions mach_msg_header_t hdr;
251*19c3b8c2SApple OSS Distributions NDR_record_t ndr;
252*19c3b8c2SApple OSS Distributions kern_return_t kr;
253*19c3b8c2SApple OSS Distributions } reply_fmt_t;
254*19c3b8c2SApple OSS Distributions #pragma pack()
255*19c3b8c2SApple OSS Distributions reply_fmt_t *reply = (reply_fmt_t *)reply_store;
256*19c3b8c2SApple OSS Distributions
257*19c3b8c2SApple OSS Distributions reply->hdr.msgh_remote_port = msg->msgh_remote_port;
258*19c3b8c2SApple OSS Distributions reply->hdr.msgh_local_port = MACH_PORT_NULL;
259*19c3b8c2SApple OSS Distributions reply->hdr.msgh_size = sizeof(*reply);
260*19c3b8c2SApple OSS Distributions reply->hdr.msgh_id = msg->msgh_id + 100;
261*19c3b8c2SApple OSS Distributions reply->kr = KERN_SUCCESS;
262*19c3b8c2SApple OSS Distributions
263*19c3b8c2SApple OSS Distributions /* try to send a voucher */
264*19c3b8c2SApple OSS Distributions reply->hdr.msgh_bits = MACH_MSGH_BITS_SET(MACH_MSG_TYPE_MOVE_SEND_ONCE,
265*19c3b8c2SApple OSS Distributions 0,
266*19c3b8c2SApple OSS Distributions MACH_MSG_TYPE_MOVE_SEND,
267*19c3b8c2SApple OSS Distributions 0);
268*19c3b8c2SApple OSS Distributions reply->hdr.msgh_voucher_port = voucher;
269*19c3b8c2SApple OSS Distributions voucher = MACH_VOUCHER_NULL;
270*19c3b8c2SApple OSS Distributions break;
271*19c3b8c2SApple OSS Distributions }
272*19c3b8c2SApple OSS Distributions
273*19c3b8c2SApple OSS Distributions case ReplyWithVoucherGarbage: {
274*19c3b8c2SApple OSS Distributions #pragma pack(4)
275*19c3b8c2SApple OSS Distributions typedef struct {
276*19c3b8c2SApple OSS Distributions mach_msg_header_t hdr;
277*19c3b8c2SApple OSS Distributions NDR_record_t ndr;
278*19c3b8c2SApple OSS Distributions kern_return_t kr;
279*19c3b8c2SApple OSS Distributions } reply_fmt_t;
280*19c3b8c2SApple OSS Distributions #pragma pack()
281*19c3b8c2SApple OSS Distributions reply_fmt_t *reply = (reply_fmt_t *)reply_store;
282*19c3b8c2SApple OSS Distributions
283*19c3b8c2SApple OSS Distributions reply->hdr.msgh_remote_port = msg->msgh_remote_port;
284*19c3b8c2SApple OSS Distributions reply->hdr.msgh_local_port = MACH_PORT_NULL;
285*19c3b8c2SApple OSS Distributions reply->hdr.msgh_size = sizeof(*reply);
286*19c3b8c2SApple OSS Distributions reply->hdr.msgh_id = msg->msgh_id + 100;
287*19c3b8c2SApple OSS Distributions reply->kr = KERN_SUCCESS;
288*19c3b8c2SApple OSS Distributions
289*19c3b8c2SApple OSS Distributions /* don't claim to send a voucher */
290*19c3b8c2SApple OSS Distributions reply->hdr.msgh_bits = MACH_MSGH_BITS_SET(MACH_MSG_TYPE_MOVE_SEND_ONCE,
291*19c3b8c2SApple OSS Distributions 0, 0, 0);
292*19c3b8c2SApple OSS Distributions /* but put some bits in the field */
293*19c3b8c2SApple OSS Distributions reply->hdr.msgh_voucher_port = (mach_voucher_t)0xdead;
294*19c3b8c2SApple OSS Distributions break;
295*19c3b8c2SApple OSS Distributions }
296*19c3b8c2SApple OSS Distributions
297*19c3b8c2SApple OSS Distributions default:
298*19c3b8c2SApple OSS Distributions T_ASSERT_FAIL("Invalid ReplyType: %d", reply_type);
299*19c3b8c2SApple OSS Distributions T_END;
300*19c3b8c2SApple OSS Distributions }
301*19c3b8c2SApple OSS Distributions
302*19c3b8c2SApple OSS Distributions if (voucher) {
303*19c3b8c2SApple OSS Distributions kr = mach_port_mod_refs(mach_task_self(), voucher,
304*19c3b8c2SApple OSS Distributions MACH_PORT_RIGHT_SEND, -1);
305*19c3b8c2SApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "destroy voucher");
306*19c3b8c2SApple OSS Distributions }
307*19c3b8c2SApple OSS Distributions
308*19c3b8c2SApple OSS Distributions T_LOG("sending exception reply of type (%s)", reply_type_str(reply_type));
309*19c3b8c2SApple OSS Distributions kr = mach_msg_send((mach_msg_header_t *)reply_store);
310*19c3b8c2SApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "exception reply msg send");
311*19c3b8c2SApple OSS Distributions
312*19c3b8c2SApple OSS Distributions T_PASS("Successfully delivered exception reply message of type %s", reply_type_str(reply_type));
313*19c3b8c2SApple OSS Distributions T_END;
314*19c3b8c2SApple OSS Distributions return NULL;
315*19c3b8c2SApple OSS Distributions }
316*19c3b8c2SApple OSS Distributions }
317*19c3b8c2SApple OSS Distributions
318*19c3b8c2SApple OSS Distributions static sigjmp_buf jb;
319*19c3b8c2SApple OSS Distributions static int *bad_pointer = NULL;
320*19c3b8c2SApple OSS Distributions static int s_sigmask = 0;
321*19c3b8c2SApple OSS Distributions
322*19c3b8c2SApple OSS Distributions static void
signal_handler(int sig,siginfo_t * sip __unused,void * ucontext __unused)323*19c3b8c2SApple OSS Distributions signal_handler(int sig, siginfo_t *sip __unused, void *ucontext __unused)
324*19c3b8c2SApple OSS Distributions {
325*19c3b8c2SApple OSS Distributions if (sigmask(sig) & s_sigmask) { /* TODO: check that the fault was generated by us */
326*19c3b8c2SApple OSS Distributions siglongjmp(jb, sig);
327*19c3b8c2SApple OSS Distributions } else {
328*19c3b8c2SApple OSS Distributions siglongjmp(jb, -sig);
329*19c3b8c2SApple OSS Distributions }
330*19c3b8c2SApple OSS Distributions }
331*19c3b8c2SApple OSS Distributions
332*19c3b8c2SApple OSS Distributions static int
handle_signals(void)333*19c3b8c2SApple OSS Distributions handle_signals(void)
334*19c3b8c2SApple OSS Distributions {
335*19c3b8c2SApple OSS Distributions int mask = 0;
336*19c3b8c2SApple OSS Distributions
337*19c3b8c2SApple OSS Distributions struct sigaction sa = {
338*19c3b8c2SApple OSS Distributions .sa_sigaction = signal_handler,
339*19c3b8c2SApple OSS Distributions .sa_flags = SA_SIGINFO
340*19c3b8c2SApple OSS Distributions };
341*19c3b8c2SApple OSS Distributions sigfillset(&sa.sa_mask);
342*19c3b8c2SApple OSS Distributions
343*19c3b8c2SApple OSS Distributions T_QUIET; T_ASSERT_POSIX_ZERO(sigaction(SIGTRAP, &sa, NULL), NULL);
344*19c3b8c2SApple OSS Distributions mask |= sigmask(SIGTRAP);
345*19c3b8c2SApple OSS Distributions
346*19c3b8c2SApple OSS Distributions T_QUIET; T_ASSERT_POSIX_ZERO(sigaction(SIGSEGV, &sa, NULL), NULL);
347*19c3b8c2SApple OSS Distributions mask |= sigmask(SIGSEGV);
348*19c3b8c2SApple OSS Distributions
349*19c3b8c2SApple OSS Distributions T_QUIET; T_ASSERT_POSIX_ZERO(sigaction(SIGILL, &sa, NULL), NULL);
350*19c3b8c2SApple OSS Distributions mask |= sigmask(SIGILL);
351*19c3b8c2SApple OSS Distributions
352*19c3b8c2SApple OSS Distributions return mask;
353*19c3b8c2SApple OSS Distributions }
354*19c3b8c2SApple OSS Distributions
355*19c3b8c2SApple OSS Distributions static void
test_exc_reply_type(ReplyType reply_type)356*19c3b8c2SApple OSS Distributions test_exc_reply_type(ReplyType reply_type)
357*19c3b8c2SApple OSS Distributions {
358*19c3b8c2SApple OSS Distributions kern_return_t kr;
359*19c3b8c2SApple OSS Distributions task_t me = mach_task_self();
360*19c3b8c2SApple OSS Distributions thread_t self = mach_thread_self();
361*19c3b8c2SApple OSS Distributions pthread_t handler_thread;
362*19c3b8c2SApple OSS Distributions pthread_attr_t attr;
363*19c3b8c2SApple OSS Distributions mach_port_t ePort;
364*19c3b8c2SApple OSS Distributions
365*19c3b8c2SApple OSS Distributions s_sigmask = handle_signals();
366*19c3b8c2SApple OSS Distributions T_LOG("task self = 0x%x, thread self = 0x%x\n", me, self);
367*19c3b8c2SApple OSS Distributions
368*19c3b8c2SApple OSS Distributions kr = mach_port_allocate(me, MACH_PORT_RIGHT_RECEIVE, &ePort);
369*19c3b8c2SApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "allocate receive right");
370*19c3b8c2SApple OSS Distributions
371*19c3b8c2SApple OSS Distributions kr = mach_port_insert_right(me, ePort, ePort, MACH_MSG_TYPE_MAKE_SEND);
372*19c3b8c2SApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "insert right into port=[%d]", ePort);
373*19c3b8c2SApple OSS Distributions
374*19c3b8c2SApple OSS Distributions kr = thread_set_exception_ports(self, EXC_MASK_ALL, ePort, EXCEPTION_DEFAULT, THREAD_STATE_NONE);
375*19c3b8c2SApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "set exception ports on self=[%d], handler=[%d]", self, ePort);
376*19c3b8c2SApple OSS Distributions
377*19c3b8c2SApple OSS Distributions pthread_attr_init(&attr);
378*19c3b8c2SApple OSS Distributions pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
379*19c3b8c2SApple OSS Distributions struct exc_thread_arg *ta = (struct exc_thread_arg *)malloc(sizeof(*ta));
380*19c3b8c2SApple OSS Distributions T_QUIET; T_ASSERT_NOTNULL(ta, "exception handler thread args allocation");
381*19c3b8c2SApple OSS Distributions ta->port = ePort;
382*19c3b8c2SApple OSS Distributions ta->rt = reply_type;
383*19c3b8c2SApple OSS Distributions
384*19c3b8c2SApple OSS Distributions T_QUIET; T_ASSERT_POSIX_SUCCESS(pthread_create(&handler_thread, &attr, handle_exceptions, (void *)ta),
385*19c3b8c2SApple OSS Distributions "pthread creation");
386*19c3b8c2SApple OSS Distributions
387*19c3b8c2SApple OSS Distributions pthread_attr_destroy(&attr);
388*19c3b8c2SApple OSS Distributions
389*19c3b8c2SApple OSS Distributions /* cause exception! */
390*19c3b8c2SApple OSS Distributions int x = sigsetjmp(jb, 0); //s_sigmask);
391*19c3b8c2SApple OSS Distributions if (x == 0) {
392*19c3b8c2SApple OSS Distributions *bad_pointer = 0;
393*19c3b8c2SApple OSS Distributions } else if (x < 0) {
394*19c3b8c2SApple OSS Distributions T_FAIL("Unexpected state on return-from-exception");
395*19c3b8c2SApple OSS Distributions T_END;
396*19c3b8c2SApple OSS Distributions } else {
397*19c3b8c2SApple OSS Distributions T_PASS("Successfully recovered from exception");
398*19c3b8c2SApple OSS Distributions T_END;
399*19c3b8c2SApple OSS Distributions }
400*19c3b8c2SApple OSS Distributions T_FAIL("Unexpected end of test!");
401*19c3b8c2SApple OSS Distributions T_END;
402*19c3b8c2SApple OSS Distributions }
403*19c3b8c2SApple OSS Distributions
404*19c3b8c2SApple OSS Distributions T_DECL(mach_exc_ReplyNoError, "exception server reply with no error",
405*19c3b8c2SApple OSS Distributions T_META_CHECK_LEAKS(false), T_META_IGNORECRASHES(".*mach_exception_reply.*"))
406*19c3b8c2SApple OSS Distributions {
407*19c3b8c2SApple OSS Distributions test_exc_reply_type(ReplyWithNoError);
408*19c3b8c2SApple OSS Distributions }
409*19c3b8c2SApple OSS Distributions T_DECL(mach_exc_ReplyWithReplyPort, "exception server reply with reply port",
410*19c3b8c2SApple OSS Distributions T_META_CHECK_LEAKS(false), T_META_IGNORECRASHES(".*mach_exception_reply.*"))
411*19c3b8c2SApple OSS Distributions {
412*19c3b8c2SApple OSS Distributions test_exc_reply_type(ReplyWithReplyPort);
413*19c3b8c2SApple OSS Distributions }
414*19c3b8c2SApple OSS Distributions T_DECL(mach_exc_ReplyWithReplyPortMove, "exception server reply with reply port as MOVE_SEND",
415*19c3b8c2SApple OSS Distributions T_META_CHECK_LEAKS(false), T_META_IGNORECRASHES(".*mach_exception_reply.*"))
416*19c3b8c2SApple OSS Distributions {
417*19c3b8c2SApple OSS Distributions test_exc_reply_type(ReplyWithReplyPortMove);
418*19c3b8c2SApple OSS Distributions }
419*19c3b8c2SApple OSS Distributions T_DECL(mach_exc_ReplyWithReplyPortCplxBit, "exception server reply with reply port and complex bit set",
420*19c3b8c2SApple OSS Distributions T_META_CHECK_LEAKS(false), T_META_IGNORECRASHES(".*mach_exception_reply.*"))
421*19c3b8c2SApple OSS Distributions {
422*19c3b8c2SApple OSS Distributions test_exc_reply_type(ReplyWithReplyPortCplxBit);
423*19c3b8c2SApple OSS Distributions }
424*19c3b8c2SApple OSS Distributions T_DECL(mach_exc_ReplyWithReplyPortMoveCplxBit, "exception server reply with reply port as MOVE_SEND and complex bit set",
425*19c3b8c2SApple OSS Distributions T_META_CHECK_LEAKS(false), T_META_IGNORECRASHES(".*mach_exception_reply.*"))
426*19c3b8c2SApple OSS Distributions {
427*19c3b8c2SApple OSS Distributions test_exc_reply_type(ReplyWithReplyPortMoveCplxBit);
428*19c3b8c2SApple OSS Distributions }
429*19c3b8c2SApple OSS Distributions T_DECL(mach_exc_ReplyWithOOLPort, "exception server reply with OOL port descriptor",
430*19c3b8c2SApple OSS Distributions T_META_CHECK_LEAKS(false), T_META_IGNORECRASHES(".*mach_exception_reply.*"))
431*19c3b8c2SApple OSS Distributions {
432*19c3b8c2SApple OSS Distributions test_exc_reply_type(ReplyWithPortDesc);
433*19c3b8c2SApple OSS Distributions }
434*19c3b8c2SApple OSS Distributions T_DECL(mach_exc_ReplyWithOOLDesc, "exception server reply with OOL memory descriptor",
435*19c3b8c2SApple OSS Distributions T_META_CHECK_LEAKS(false), T_META_IGNORECRASHES(".*mach_exception_reply.*"))
436*19c3b8c2SApple OSS Distributions {
437*19c3b8c2SApple OSS Distributions test_exc_reply_type(ReplyWithOOLDesc);
438*19c3b8c2SApple OSS Distributions }
439*19c3b8c2SApple OSS Distributions T_DECL(mach_exc_ReplyWithVoucher, "exception server reply with a voucher",
440*19c3b8c2SApple OSS Distributions T_META_CHECK_LEAKS(false), T_META_IGNORECRASHES(".*mach_exception_reply.*"))
441*19c3b8c2SApple OSS Distributions {
442*19c3b8c2SApple OSS Distributions test_exc_reply_type(ReplyWithVoucher);
443*19c3b8c2SApple OSS Distributions }
444*19c3b8c2SApple OSS Distributions T_DECL(mach_exc_ReplyWithVoucherGarbage, "exception server reply with bits in msgh_voucher_port",
445*19c3b8c2SApple OSS Distributions T_META_CHECK_LEAKS(false), T_META_IGNORECRASHES(".*mach_exception_reply.*"))
446*19c3b8c2SApple OSS Distributions {
447*19c3b8c2SApple OSS Distributions test_exc_reply_type(ReplyWithVoucherGarbage);
448*19c3b8c2SApple OSS Distributions }
449