xref: /xnu-11215.41.3/libsyscall/mach/mach_port.c (revision 33de042d024d46de5ff4e89f2471de6608e37fa4)
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