1 /*
2 * Copyright (c) 2011 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29 #include <mach/mach_port_internal.h>
30 #include <mach/mach.h>
31 #include <mach/mach_vm.h>
32 #include <mach/mach_traps.h>
33 #include <mach/mach_sync_ipc.h>
34 #include "tsd.h"
35
36
37 kern_return_t
mach_port_names(ipc_space_t task,mach_port_name_array_t * names,mach_msg_type_number_t * namesCnt,mach_port_type_array_t * types,mach_msg_type_number_t * typesCnt)38 mach_port_names(
39 ipc_space_t task,
40 mach_port_name_array_t *names,
41 mach_msg_type_number_t *namesCnt,
42 mach_port_type_array_t *types,
43 mach_msg_type_number_t *typesCnt)
44 {
45 kern_return_t rv;
46
47 rv = _kernelrpc_mach_port_names(task, names, namesCnt, types,
48 typesCnt);
49
50 return rv;
51 }
52
53 kern_return_t
mach_port_type(ipc_space_t task,mach_port_name_t name,mach_port_type_t * ptype)54 mach_port_type(
55 ipc_space_t task,
56 mach_port_name_t name,
57 mach_port_type_t *ptype)
58 {
59 kern_return_t rv;
60
61 rv = _kernelrpc_mach_port_type_trap(task, name, ptype);
62
63 if (rv == MACH_SEND_INVALID_DEST) {
64 rv = _kernelrpc_mach_port_type(task, name, ptype);
65 }
66
67 return rv;
68 }
69
70 kern_return_t
mach_port_rename(ipc_space_t task,mach_port_name_t old_name,mach_port_name_t new_name)71 mach_port_rename(
72 ipc_space_t task,
73 mach_port_name_t old_name,
74 mach_port_name_t new_name)
75 {
76 kern_return_t rv;
77
78 rv = _kernelrpc_mach_port_rename(task, old_name, new_name);
79
80 return rv;
81 }
82
83 kern_return_t
mach_port_allocate_name(ipc_space_t task,mach_port_right_t right,mach_port_name_t name)84 mach_port_allocate_name(
85 ipc_space_t task,
86 mach_port_right_t right,
87 mach_port_name_t name)
88 {
89 kern_return_t rv;
90
91 rv = _kernelrpc_mach_port_allocate_name(task, right, name);
92
93 return rv;
94 }
95
96 kern_return_t
mach_port_allocate(ipc_space_t task,mach_port_right_t right,mach_port_name_t * name)97 mach_port_allocate(
98 ipc_space_t task,
99 mach_port_right_t right,
100 mach_port_name_t *name)
101 {
102 kern_return_t rv;
103
104 rv = _kernelrpc_mach_port_allocate_trap(task, right, name);
105
106 if (rv == MACH_SEND_INVALID_DEST) {
107 rv = _kernelrpc_mach_port_allocate(task, right, name);
108 }
109
110 return rv;
111 }
112
113 kern_return_t
mach_port_destroy(ipc_space_t task,mach_port_name_t name)114 mach_port_destroy(
115 ipc_space_t task,
116 mach_port_name_t name)
117 {
118 kern_return_t rv;
119
120 rv = _kernelrpc_mach_port_destroy(task, name);
121
122 return rv;
123 }
124
125 kern_return_t
mach_port_deallocate(ipc_space_t task,mach_port_name_t name)126 mach_port_deallocate(
127 ipc_space_t task,
128 mach_port_name_t name)
129 {
130 kern_return_t rv;
131
132 rv = _kernelrpc_mach_port_deallocate_trap(task, name);
133
134 if (rv == MACH_SEND_INVALID_DEST) {
135 rv = _kernelrpc_mach_port_deallocate(task, name);
136 }
137
138 return rv;
139 }
140
141 kern_return_t
mach_port_get_refs(ipc_space_t task,mach_port_name_t name,mach_port_right_t right,mach_port_urefs_t * refs)142 mach_port_get_refs(
143 ipc_space_t task,
144 mach_port_name_t name,
145 mach_port_right_t right,
146 mach_port_urefs_t *refs)
147 {
148 kern_return_t rv;
149
150 rv = _kernelrpc_mach_port_get_refs(task, name, right, refs);
151
152 return rv;
153 }
154
155 kern_return_t
mach_port_mod_refs(ipc_space_t task,mach_port_name_t name,mach_port_right_t right,mach_port_delta_t delta)156 mach_port_mod_refs(
157 ipc_space_t task,
158 mach_port_name_t name,
159 mach_port_right_t right,
160 mach_port_delta_t delta)
161 {
162 kern_return_t rv;
163
164 rv = _kernelrpc_mach_port_mod_refs_trap(task, name, right, delta);
165
166 if (rv == MACH_SEND_INVALID_DEST) {
167 rv = _kernelrpc_mach_port_mod_refs(task, name, right, delta);
168 }
169
170 return rv;
171 }
172
173 kern_return_t
mach_port_peek(ipc_space_t task,mach_port_name_t name,mach_msg_trailer_type_t trailer_type,mach_port_seqno_t * seqnop,mach_msg_size_t * msg_sizep,mach_msg_id_t * msg_idp,mach_msg_trailer_info_t trailer_infop,mach_msg_type_number_t * trailer_sizep)174 mach_port_peek(
175 ipc_space_t task,
176 mach_port_name_t name,
177 mach_msg_trailer_type_t trailer_type,
178 mach_port_seqno_t *seqnop,
179 mach_msg_size_t *msg_sizep,
180 mach_msg_id_t *msg_idp,
181 mach_msg_trailer_info_t trailer_infop,
182 mach_msg_type_number_t *trailer_sizep)
183 {
184 kern_return_t rv;
185
186 rv = _kernelrpc_mach_port_peek(task, name, trailer_type,
187 seqnop, msg_sizep, msg_idp,
188 trailer_infop, trailer_sizep);
189
190 return rv;
191 }
192
193 kern_return_t
mach_port_set_mscount(ipc_space_t task,mach_port_name_t name,mach_port_mscount_t mscount)194 mach_port_set_mscount(
195 ipc_space_t task,
196 mach_port_name_t name,
197 mach_port_mscount_t mscount)
198 {
199 kern_return_t rv;
200
201 rv = _kernelrpc_mach_port_set_mscount(task, name, mscount);
202
203 return rv;
204 }
205
206 kern_return_t
mach_port_get_set_status(ipc_space_t task,mach_port_name_t name,mach_port_name_array_t * members,mach_msg_type_number_t * membersCnt)207 mach_port_get_set_status(
208 ipc_space_t task,
209 mach_port_name_t name,
210 mach_port_name_array_t *members,
211 mach_msg_type_number_t *membersCnt)
212 {
213 kern_return_t rv;
214
215 rv = _kernelrpc_mach_port_get_set_status(task, name, members,
216 membersCnt);
217
218 return rv;
219 }
220
221 kern_return_t
mach_port_move_member(ipc_space_t task,mach_port_name_t member,mach_port_name_t after)222 mach_port_move_member(
223 ipc_space_t task,
224 mach_port_name_t member,
225 mach_port_name_t after)
226 {
227 kern_return_t rv;
228
229 rv = _kernelrpc_mach_port_move_member_trap(task, member, after);
230
231 if (rv == MACH_SEND_INVALID_DEST) {
232 rv = _kernelrpc_mach_port_move_member(task, member, after);
233 }
234
235 return rv;
236 }
237
238 kern_return_t
mach_port_request_notification(ipc_space_t task,mach_port_name_t name,mach_msg_id_t msgid,mach_port_mscount_t sync,mach_port_t notify,mach_msg_type_name_t notifyPoly,mach_port_t * previous)239 mach_port_request_notification(
240 ipc_space_t task,
241 mach_port_name_t name,
242 mach_msg_id_t msgid,
243 mach_port_mscount_t sync,
244 mach_port_t notify,
245 mach_msg_type_name_t notifyPoly,
246 mach_port_t *previous)
247 {
248 kern_return_t rv;
249
250 rv = _kernelrpc_mach_port_request_notification_trap(task, name, msgid,
251 sync, notify, notifyPoly, previous);
252
253 if (rv == MACH_SEND_INVALID_DEST) {
254 rv = _kernelrpc_mach_port_request_notification(task, name, msgid,
255 sync, notify, notifyPoly, previous);
256 }
257
258 return rv;
259 }
260
261 kern_return_t
mach_port_insert_right(ipc_space_t task,mach_port_name_t name,mach_port_t poly,mach_msg_type_name_t polyPoly)262 mach_port_insert_right(
263 ipc_space_t task,
264 mach_port_name_t name,
265 mach_port_t poly,
266 mach_msg_type_name_t polyPoly)
267 {
268 kern_return_t rv;
269
270 rv = _kernelrpc_mach_port_insert_right_trap(task, name, poly, polyPoly);
271
272 if (rv == MACH_SEND_INVALID_DEST) {
273 rv = _kernelrpc_mach_port_insert_right(task, name, poly,
274 polyPoly);
275 }
276
277 return rv;
278 }
279
280 kern_return_t
mach_port_extract_right(ipc_space_t task,mach_port_name_t name,mach_msg_type_name_t msgt_name,mach_port_t * poly,mach_msg_type_name_t * polyPoly)281 mach_port_extract_right(
282 ipc_space_t task,
283 mach_port_name_t name,
284 mach_msg_type_name_t msgt_name,
285 mach_port_t *poly,
286 mach_msg_type_name_t *polyPoly)
287 {
288 kern_return_t rv;
289
290 rv = _kernelrpc_mach_port_extract_right(task, name, msgt_name,
291 poly, polyPoly);
292
293 return rv;
294 }
295
296 kern_return_t
mach_port_set_seqno(ipc_space_t task,mach_port_name_t name,mach_port_seqno_t seqno)297 mach_port_set_seqno(
298 ipc_space_t task,
299 mach_port_name_t name,
300 mach_port_seqno_t seqno)
301 {
302 kern_return_t rv;
303
304 rv = _kernelrpc_mach_port_set_seqno(task, name, seqno);
305
306 return rv;
307 }
308
309 kern_return_t
mach_port_get_attributes(ipc_space_t task,mach_port_name_t name,mach_port_flavor_t flavor,mach_port_info_t port_info_out,mach_msg_type_number_t * port_info_outCnt)310 mach_port_get_attributes(
311 ipc_space_t task,
312 mach_port_name_t name,
313 mach_port_flavor_t flavor,
314 mach_port_info_t port_info_out,
315 mach_msg_type_number_t *port_info_outCnt)
316 {
317 kern_return_t rv;
318
319 rv = _kernelrpc_mach_port_get_attributes_trap(task, name, flavor,
320 port_info_out, port_info_outCnt);
321
322 #ifdef __x86_64__
323 /* REMOVE once XBS kernel has new trap */
324 if (rv == ((1 << 24) | 40)) { /* see mach/i386/syscall_sw.h */
325 rv = MACH_SEND_INVALID_DEST;
326 }
327 #elif defined(__i386__)
328 /* REMOVE once XBS kernel has new trap */
329 if (rv == (kern_return_t)(-40)) {
330 rv = MACH_SEND_INVALID_DEST;
331 }
332 #endif
333
334 if (rv == MACH_SEND_INVALID_DEST) {
335 rv = _kernelrpc_mach_port_get_attributes(task, name, flavor,
336 port_info_out, port_info_outCnt);
337 }
338
339 return rv;
340 }
341
342 kern_return_t
mach_port_set_attributes(ipc_space_t task,mach_port_name_t name,mach_port_flavor_t flavor,mach_port_info_t port_info,mach_msg_type_number_t port_infoCnt)343 mach_port_set_attributes(
344 ipc_space_t task,
345 mach_port_name_t name,
346 mach_port_flavor_t flavor,
347 mach_port_info_t port_info,
348 mach_msg_type_number_t port_infoCnt)
349 {
350 kern_return_t rv;
351
352 rv = _kernelrpc_mach_port_set_attributes(task, name, flavor,
353 port_info, port_infoCnt);
354
355 return rv;
356 }
357
358 kern_return_t
mach_port_allocate_qos(ipc_space_t task,mach_port_right_t right,mach_port_qos_t * qos,mach_port_name_t * name)359 mach_port_allocate_qos(
360 ipc_space_t task,
361 mach_port_right_t right,
362 mach_port_qos_t *qos,
363 mach_port_name_t *name)
364 {
365 kern_return_t rv;
366
367 rv = _kernelrpc_mach_port_allocate_qos(task, right, qos, name);
368
369 return rv;
370 }
371
372 kern_return_t
mach_port_allocate_full(ipc_space_t task,mach_port_right_t right,mach_port_t proto,mach_port_qos_t * qos,mach_port_name_t * name)373 mach_port_allocate_full(
374 ipc_space_t task,
375 mach_port_right_t right,
376 mach_port_t proto,
377 mach_port_qos_t *qos,
378 mach_port_name_t *name)
379 {
380 kern_return_t rv;
381
382 rv = _kernelrpc_mach_port_allocate_full(task, right, proto, qos, name);
383
384 return rv;
385 }
386
387 kern_return_t
task_set_port_space(ipc_space_t task,int table_entries)388 task_set_port_space(
389 ipc_space_t task,
390 int table_entries)
391 {
392 kern_return_t rv;
393
394 rv = _kernelrpc_task_set_port_space(task, table_entries);
395
396 return rv;
397 }
398
399 kern_return_t
mach_port_get_srights(ipc_space_t task,mach_port_name_t name,mach_port_rights_t * srights)400 mach_port_get_srights(
401 ipc_space_t task,
402 mach_port_name_t name,
403 mach_port_rights_t *srights)
404 {
405 kern_return_t rv;
406
407 rv = _kernelrpc_mach_port_get_srights(task, name, srights);
408
409 return rv;
410 }
411
412 kern_return_t
mach_port_space_info(ipc_space_t task,ipc_info_space_t * space_info,ipc_info_name_array_t * table_info,mach_msg_type_number_t * table_infoCnt,ipc_info_tree_name_array_t * tree_info,mach_msg_type_number_t * tree_infoCnt)413 mach_port_space_info(
414 ipc_space_t task,
415 ipc_info_space_t *space_info,
416 ipc_info_name_array_t *table_info,
417 mach_msg_type_number_t *table_infoCnt,
418 ipc_info_tree_name_array_t *tree_info,
419 mach_msg_type_number_t *tree_infoCnt)
420 {
421 kern_return_t rv;
422
423 rv = _kernelrpc_mach_port_space_info(task, space_info, table_info,
424 table_infoCnt, tree_info, tree_infoCnt);
425
426 return rv;
427 }
428
429 kern_return_t
mach_port_space_basic_info(ipc_space_t task,ipc_info_space_basic_t * space_basic_info)430 mach_port_space_basic_info(
431 ipc_space_t task,
432 ipc_info_space_basic_t *space_basic_info)
433 {
434 kern_return_t rv;
435
436 rv = _kernelrpc_mach_port_space_basic_info(task, space_basic_info);
437
438 return rv;
439 }
440
441 static inline mach_port_t
_tsd_get_special_reply_port(void)442 _tsd_get_special_reply_port(void)
443 {
444 return (mach_port_t)(uintptr_t)_os_tsd_get_direct(__TSD_MACH_SPECIAL_REPLY);
445 }
446
447 static inline void
_tsd_set_special_reply_port(mach_port_t port)448 _tsd_set_special_reply_port(mach_port_t port)
449 {
450 _os_tsd_set_direct(__TSD_MACH_SPECIAL_REPLY, (void *)(uintptr_t)port);
451 }
452
453 mach_port_t
mig_get_special_reply_port(void)454 mig_get_special_reply_port(void)
455 {
456 mach_port_t srp;
457
458 srp = _tsd_get_special_reply_port();
459 if (!MACH_PORT_VALID(srp)) {
460 srp = thread_get_special_reply_port();
461 _tsd_set_special_reply_port(srp);
462 }
463
464 return srp;
465 }
466
467 void
mig_dealloc_special_reply_port(mach_port_t migport)468 mig_dealloc_special_reply_port(mach_port_t migport)
469 {
470 mach_port_t srp = _tsd_get_special_reply_port();
471 if (MACH_PORT_VALID(srp)) {
472 thread_destruct_special_reply_port(srp, THREAD_SPECIAL_REPLY_PORT_ALL);
473 if (migport != srp) {
474 mach_port_deallocate(mach_task_self(), migport);
475 }
476 _tsd_set_special_reply_port(MACH_PORT_NULL);
477 }
478 }
479
480 kern_return_t
mach_sync_ipc_link_monitoring_start(mach_port_t * special_reply_port)481 mach_sync_ipc_link_monitoring_start(mach_port_t *special_reply_port)
482 {
483 mach_port_t srp;
484 boolean_t link_broken;
485 kern_return_t kr;
486
487 *special_reply_port = MACH_PORT_DEAD;
488
489 srp = mig_get_special_reply_port();
490
491 kr = mach_port_mod_refs(mach_task_self(), srp, MACH_PORT_RIGHT_SEND, 1);
492
493 if (kr != KERN_SUCCESS) {
494 return kr;
495 }
496
497 kr = _kernelrpc_mach_port_special_reply_port_reset_link(mach_task_self(), srp, &link_broken);
498 if (kr != KERN_SUCCESS) {
499 mach_port_deallocate(mach_task_self(), srp);
500 return kr;
501 }
502
503 *special_reply_port = srp;
504
505 return kr;
506 }
507
508 kern_return_t
mach_sync_ipc_link_monitoring_stop(mach_port_t srp,boolean_t * in_effect)509 mach_sync_ipc_link_monitoring_stop(mach_port_t srp, boolean_t* in_effect)
510 {
511 kern_return_t kr;
512 boolean_t link_broken = TRUE;
513
514 kr = _kernelrpc_mach_port_special_reply_port_reset_link(mach_task_self(), srp, &link_broken);
515
516 /*
517 * We return if the sync IPC priority inversion avoidance facility took
518 * effect, so if the link was broken it didn't take effect.
519 * Flip the return.
520 */
521 *in_effect = !link_broken;
522
523 mach_port_deallocate(mach_task_self(), srp);
524
525 return kr;
526 }
527
528 kern_return_t
mach_port_dnrequest_info(ipc_space_t task,mach_port_name_t name,unsigned * dnr_total,unsigned * dnr_used)529 mach_port_dnrequest_info(
530 ipc_space_t task,
531 mach_port_name_t name,
532 unsigned *dnr_total,
533 unsigned *dnr_used)
534 {
535 kern_return_t rv;
536
537 rv = _kernelrpc_mach_port_dnrequest_info(task, name, dnr_total,
538 dnr_used);
539
540 return rv;
541 }
542
543 kern_return_t
mach_port_kernel_object(ipc_space_t task,mach_port_name_t name,unsigned * object_type,unsigned * object_addr)544 mach_port_kernel_object(
545 ipc_space_t task,
546 mach_port_name_t name,
547 unsigned *object_type,
548 unsigned *object_addr)
549 {
550 kern_return_t rv;
551 mach_vm_address_t addr;
552
553 rv = _kernelrpc_mach_port_kobject(task, name,
554 object_type, &addr);
555
556 if (rv == KERN_SUCCESS && object_addr) {
557 *object_addr = (unsigned)addr;
558 }
559
560 return rv;
561 }
562
563 kern_return_t
mach_port_insert_member(ipc_space_t task,mach_port_name_t name,mach_port_name_t pset)564 mach_port_insert_member(
565 ipc_space_t task,
566 mach_port_name_t name,
567 mach_port_name_t pset)
568 {
569 kern_return_t rv;
570
571 rv = _kernelrpc_mach_port_insert_member_trap(task, name, pset);
572
573 if (rv == MACH_SEND_INVALID_DEST) {
574 rv = _kernelrpc_mach_port_insert_member(task, name, pset);
575 }
576
577 return rv;
578 }
579
580 kern_return_t
mach_port_extract_member(ipc_space_t task,mach_port_name_t name,mach_port_name_t pset)581 mach_port_extract_member(
582 ipc_space_t task,
583 mach_port_name_t name,
584 mach_port_name_t pset)
585 {
586 kern_return_t rv;
587
588 rv = _kernelrpc_mach_port_extract_member_trap(task, name, pset);
589
590 if (rv == MACH_SEND_INVALID_DEST) {
591 rv = _kernelrpc_mach_port_extract_member(task, name, pset);
592 }
593
594 return rv;
595 }
596
597 kern_return_t
mach_port_get_context(ipc_space_t task,mach_port_name_t name,mach_port_context_t * context)598 mach_port_get_context(
599 ipc_space_t task,
600 mach_port_name_t name,
601 mach_port_context_t *context)
602 {
603 kern_return_t rv;
604 mach_vm_address_t wide_context;
605
606 rv = _kernelrpc_mach_port_get_context(task, name, &wide_context);
607
608 if (rv == KERN_SUCCESS) {
609 *context = (mach_port_context_t)wide_context;
610 }
611
612 return rv;
613 }
614
615 kern_return_t
mach_port_set_context(ipc_space_t task,mach_port_name_t name,mach_port_context_t context)616 mach_port_set_context(
617 ipc_space_t task,
618 mach_port_name_t name,
619 mach_port_context_t context)
620 {
621 kern_return_t rv;
622
623 rv = _kernelrpc_mach_port_set_context(task, name, context);
624
625 return rv;
626 }
627
628 kern_return_t
mach_port_kobject(ipc_space_t task,mach_port_name_t name,natural_t * object_type,mach_vm_address_t * object_addr)629 mach_port_kobject(
630 ipc_space_t task,
631 mach_port_name_t name,
632 natural_t *object_type,
633 mach_vm_address_t *object_addr)
634 {
635 kern_return_t rv;
636
637 rv = _kernelrpc_mach_port_kobject(task, name, object_type, object_addr);
638
639 return rv;
640 }
641
642 kern_return_t
mach_port_kobject_description(ipc_space_t task,mach_port_name_t name,natural_t * object_type,mach_vm_address_t * object_addr,kobject_description_t desc)643 mach_port_kobject_description(
644 ipc_space_t task,
645 mach_port_name_t name,
646 natural_t *object_type,
647 mach_vm_address_t *object_addr,
648 kobject_description_t desc)
649 {
650 kern_return_t rv;
651
652 rv = _kernelrpc_mach_port_kobject_description(task, name, object_type, object_addr, desc);
653
654 return rv;
655 }
656
657 kern_return_t
mach_port_construct(ipc_space_t task,mach_port_options_t * options,mach_port_context_t context,mach_port_name_t * name)658 mach_port_construct(
659 ipc_space_t task,
660 mach_port_options_t *options,
661 mach_port_context_t context,
662 mach_port_name_t *name)
663 {
664 kern_return_t rv;
665
666 rv = _kernelrpc_mach_port_construct_trap(task, options, (uint64_t) context, name);
667
668 if (rv == MACH_SEND_INVALID_DEST) {
669 rv = _kernelrpc_mach_port_construct(task, options, (uint64_t) context, name);
670 }
671
672 return rv;
673 }
674
675 kern_return_t
mach_port_destruct(ipc_space_t task,mach_port_name_t name,mach_port_delta_t srdelta,mach_port_context_t guard)676 mach_port_destruct(
677 ipc_space_t task,
678 mach_port_name_t name,
679 mach_port_delta_t srdelta,
680 mach_port_context_t guard)
681 {
682 kern_return_t rv;
683
684 rv = _kernelrpc_mach_port_destruct_trap(task, name, srdelta, (uint64_t) guard);
685
686 if (rv == MACH_SEND_INVALID_DEST) {
687 rv = _kernelrpc_mach_port_destruct(task, name, srdelta, (uint64_t) guard);
688 }
689
690 return rv;
691 }
692
693 kern_return_t
mach_port_guard(ipc_space_t task,mach_port_name_t name,mach_port_context_t guard,boolean_t strict)694 mach_port_guard(
695 ipc_space_t task,
696 mach_port_name_t name,
697 mach_port_context_t guard,
698 boolean_t strict)
699 {
700 kern_return_t rv;
701
702 rv = _kernelrpc_mach_port_guard_trap(task, name, (uint64_t) guard, strict);
703
704 if (rv == MACH_SEND_INVALID_DEST) {
705 rv = _kernelrpc_mach_port_guard(task, name, (uint64_t) guard, strict);
706 }
707
708 return rv;
709 }
710
711 kern_return_t
mach_port_unguard(ipc_space_t task,mach_port_name_t name,mach_port_context_t guard)712 mach_port_unguard(
713 ipc_space_t task,
714 mach_port_name_t name,
715 mach_port_context_t guard)
716 {
717 kern_return_t rv;
718
719 rv = _kernelrpc_mach_port_unguard_trap(task, name, (uint64_t) guard);
720
721 if (rv == MACH_SEND_INVALID_DEST) {
722 rv = _kernelrpc_mach_port_unguard(task, name, (uint64_t) guard);
723 }
724
725 return rv;
726 }
727
728 extern kern_return_t
729 _kernelrpc_mach_voucher_extract_attr_recipe(
730 mach_port_name_t voucher,
731 mach_voucher_attr_key_t key,
732 mach_voucher_attr_raw_recipe_t recipe,
733 mach_msg_type_number_t *recipe_size);
734
735 kern_return_t
mach_voucher_extract_attr_recipe(mach_port_name_t voucher,mach_voucher_attr_key_t key,mach_voucher_attr_raw_recipe_t recipe,mach_msg_type_number_t * recipe_size)736 mach_voucher_extract_attr_recipe(
737 mach_port_name_t voucher,
738 mach_voucher_attr_key_t key,
739 mach_voucher_attr_raw_recipe_t recipe,
740 mach_msg_type_number_t *recipe_size)
741 {
742 kern_return_t rv;
743
744 rv = mach_voucher_extract_attr_recipe_trap(voucher, key, recipe, recipe_size);
745
746 if (rv == MACH_SEND_INVALID_DEST) {
747 rv = _kernelrpc_mach_voucher_extract_attr_recipe(voucher, key, recipe, recipe_size);
748 }
749
750 return rv;
751 }
752
753
754 kern_return_t
thread_destruct_special_reply_port(mach_port_name_t port,thread_destruct_special_reply_port_rights_t rights)755 thread_destruct_special_reply_port(
756 mach_port_name_t port,
757 thread_destruct_special_reply_port_rights_t rights)
758 {
759 switch (rights) {
760 case THREAD_SPECIAL_REPLY_PORT_ALL:
761 return mach_port_destruct(mach_task_self(), port, -1, 0);
762
763 case THREAD_SPECIAL_REPLY_PORT_RECEIVE_ONLY:
764 return mach_port_destruct(mach_task_self(), port, 0, 0);
765
766 case THREAD_SPECIAL_REPLY_PORT_SEND_ONLY:
767 return mach_port_deallocate(mach_task_self(), port);
768
769 default:
770 return KERN_INVALID_ARGUMENT;
771 }
772 }
773
774 kern_return_t
mach_port_guard_with_flags(ipc_space_t task,mach_port_name_t name,mach_port_context_t guard,uint64_t flags)775 mach_port_guard_with_flags(
776 ipc_space_t task,
777 mach_port_name_t name,
778 mach_port_context_t guard,
779 uint64_t flags)
780 {
781 kern_return_t rv;
782
783 rv = _kernelrpc_mach_port_guard_with_flags(task, name, (uint64_t) guard, flags);
784
785 return rv;
786 }
787
788 kern_return_t
mach_port_swap_guard(ipc_space_t task,mach_port_name_t name,mach_port_context_t old_guard,mach_port_context_t new_guard)789 mach_port_swap_guard(
790 ipc_space_t task,
791 mach_port_name_t name,
792 mach_port_context_t old_guard,
793 mach_port_context_t new_guard)
794 {
795 kern_return_t rv;
796
797 rv = _kernelrpc_mach_port_swap_guard(task, name, (uint64_t)old_guard, (uint64_t)new_guard);
798
799 return rv;
800 }
801
802 kern_return_t
mach_port_is_connection_for_service(ipc_space_t task,mach_port_name_t connection_port_name,mach_port_name_t service_port_name,uint64_t * filter_policy_id)803 mach_port_is_connection_for_service(
804 ipc_space_t task,
805 mach_port_name_t connection_port_name,
806 mach_port_name_t service_port_name,
807 uint64_t *filter_policy_id)
808 {
809 kern_return_t rv;
810
811 rv = _kernelrpc_mach_port_is_connection_for_service(task, connection_port_name, service_port_name, filter_policy_id);
812
813 return rv;
814 }
815
816 kern_return_t
mach_port_get_service_port_info(ipc_space_read_t task,mach_port_name_t name,mach_service_port_info_data_t * sp_info_out)817 mach_port_get_service_port_info(
818 ipc_space_read_t task,
819 mach_port_name_t name,
820 mach_service_port_info_data_t *sp_info_out)
821 {
822 kern_return_t rv;
823
824 rv = _kernelrpc_mach_port_get_service_port_info(task, name, sp_info_out);
825
826 return rv;
827 }
828
829 kern_return_t
mach_port_assert_attributes(ipc_space_t task,mach_port_name_t name,mach_port_flavor_t flavor,mach_port_info_t info,mach_msg_type_number_t infoCnt)830 mach_port_assert_attributes(
831 ipc_space_t task,
832 mach_port_name_t name,
833 mach_port_flavor_t flavor,
834 mach_port_info_t info,
835 mach_msg_type_number_t infoCnt)
836 {
837 kern_return_t rv;
838
839 rv = _kernelrpc_mach_port_assert_attributes(task, name, flavor,
840 info, infoCnt);
841
842 return rv;
843 }
844