xref: /xnu-11417.140.69/bsd/kern/kern_proc.c (revision 43a90889846e00bfb5cf1d255cdc0a701a1e05a4)
1 /*
2  * Copyright (c) 2000-2020 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 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
29 /*
30  * Copyright (c) 1982, 1986, 1989, 1991, 1993
31  *	The Regents of the University of California.  All rights reserved.
32  *
33  * Redistribution and use in source and binary forms, with or without
34  * modification, are permitted provided that the following conditions
35  * are met:
36  * 1. Redistributions of source code must retain the above copyright
37  *    notice, this list of conditions and the following disclaimer.
38  * 2. Redistributions in binary form must reproduce the above copyright
39  *    notice, this list of conditions and the following disclaimer in the
40  *    documentation and/or other materials provided with the distribution.
41  * 3. All advertising materials mentioning features or use of this software
42  *    must display the following acknowledgement:
43  *	This product includes software developed by the University of
44  *	California, Berkeley and its contributors.
45  * 4. Neither the name of the University nor the names of its contributors
46  *    may be used to endorse or promote products derived from this software
47  *    without specific prior written permission.
48  *
49  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59  * SUCH DAMAGE.
60  *
61  *	@(#)kern_proc.c	8.4 (Berkeley) 1/4/94
62  */
63 /*
64  * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce
65  * support for mandatory and extensible security protections.  This notice
66  * is included in support of clause 2.2 (b) of the Apple Public License,
67  * Version 2.0.
68  */
69 /* HISTORY
70  *  04-Aug-97  Umesh Vaishampayan ([email protected])
71  *	Added current_proc_EXTERNAL() function for the use of kernel
72  *      lodable modules.
73  *
74  *  05-Jun-95 Mac Gillon (mgillon) at NeXT
75  *	New version based on 3.3NS and 4.4
76  */
77 
78 
79 #include <sys/param.h>
80 #include <sys/systm.h>
81 #include <sys/kernel.h>
82 #include <sys/proc_internal.h>
83 #include <sys/acct.h>
84 #include <sys/wait.h>
85 #include <sys/file_internal.h>
86 #include <sys/uio.h>
87 #include <sys/malloc.h>
88 #include <sys/lock.h>
89 #include <sys/mbuf.h>
90 #include <sys/ioctl.h>
91 #include <sys/tty.h>
92 #include <sys/signalvar.h>
93 #include <sys/syslog.h>
94 #include <sys/sysctl.h>
95 #include <sys/sysproto.h>
96 #include <sys/kauth.h>
97 #include <sys/codesign.h>
98 #include <sys/kernel_types.h>
99 #include <sys/ubc.h>
100 #include <kern/clock.h>
101 #include <kern/debug.h>
102 #include <kern/kalloc.h>
103 #include <kern/smr_hash.h>
104 #include <kern/task.h>
105 #include <kern/coalition.h>
106 #include <kern/cs_blobs.h>
107 #include <sys/coalition.h>
108 #include <kern/assert.h>
109 #include <kern/sched_prim.h>
110 #include <vm/vm_protos.h>
111 #include <vm/vm_map_xnu.h>          /* vm_map_switch_protect() */
112 #include <vm/vm_pageout.h>
113 #include <vm/vm_compressor_xnu.h>
114 #include <mach/task.h>
115 #include <mach/message.h>
116 #include <sys/priv.h>
117 #include <sys/proc_info.h>
118 #include <sys/bsdtask_info.h>
119 #include <sys/persona.h>
120 #include <sys/sysent.h>
121 #include <sys/reason.h>
122 #include <sys/proc_require.h>
123 #include <sys/kern_debug.h>
124 #include <sys/kern_memorystatus_xnu.h>
125 #include <IOKit/IOBSD.h>        /* IOTaskHasEntitlement() */
126 #include <kern/kern_memorystatus_internal.h>
127 #include <kern/ipc_kobject.h>   /* ipc_kobject_set_kobjidx() */
128 #include <kern/ast.h>           /* proc_filedesc_ast */
129 #include <libkern/amfi/amfi.h>
130 #include <mach-o/loader.h>
131 #include <os/base.h>            /* OS_STRINGIFY */
132 
133 #if CONFIG_CSR
134 #include <sys/csr.h>
135 #endif
136 
137 #if CONFIG_MACF
138 #include <security/mac_framework.h>
139 #include <security/mac_mach_internal.h>
140 #endif
141 #include <security/audit/audit.h>
142 
143 #include <libkern/crypto/sha1.h>
144 #include <IOKit/IOKitKeys.h>
145 #include <mach/mach_traps.h>
146 #include <mach/task_access.h>
147 #include <kern/extmod_statistics.h>
148 #include <security/mac.h>
149 #include <sys/socketvar.h>
150 #include <sys/kern_memorystatus_freeze.h>
151 #include <net/necp.h>
152 #include <bsm/audit_kevents.h>
153 
154 #ifdef XNU_KERNEL_PRIVATE
155 #include <corpses/task_corpse.h>
156 #endif /* XNU_KERNEL_PRIVATE */
157 
158 #if SKYWALK
159 #include <skywalk/core/skywalk_var.h>
160 #endif /* SKYWALK */
161 /*
162  * Structure associated with user cacheing.
163  */
164 struct uidinfo {
165 	LIST_ENTRY(uidinfo) ui_hash;
166 	uid_t   ui_uid;
167 	size_t    ui_proccnt;
168 };
169 #define UIHASH(uid)     (&uihashtbl[(uid) & uihash])
170 static LIST_HEAD(uihashhead, uidinfo) * uihashtbl;
171 static u_long uihash;          /* size of hash table - 1 */
172 
173 /*
174  * Other process lists
175  */
176 static struct smr_hash pid_hash;
177 static struct smr_hash pgrp_hash;
178 
179 SECURITY_READ_ONLY_LATE(struct sesshashhead *) sesshashtbl;
180 SECURITY_READ_ONLY_LATE(u_long) sesshash;
181 
182 struct proclist allproc = LIST_HEAD_INITIALIZER(allproc);
183 struct proclist zombproc = LIST_HEAD_INITIALIZER(zombproc);
184 extern struct tty cons;
185 extern size_t proc_struct_size;
186 extern size_t proc_and_task_size;
187 
188 extern int cs_debug;
189 
190 #if DEVELOPMENT || DEBUG
191 static TUNABLE(bool, syscallfilter_disable, "-disable_syscallfilter", false);
192 #endif // DEVELOPMENT || DEBUG
193 
194 #if DEBUG
195 #define __PROC_INTERNAL_DEBUG 1
196 #endif
197 #if CONFIG_COREDUMP
198 /* Name to give to core files */
199 #if defined(XNU_TARGET_OS_BRIDGE)
200 __XNU_PRIVATE_EXTERN const char * defaultcorefiledir = "/private/var/internal";
201 __XNU_PRIVATE_EXTERN char corefilename[MAXPATHLEN + 1] = {"/private/var/internal/%N.core"};
202 __XNU_PRIVATE_EXTERN const char * defaultdrivercorefiledir = "/private/var/internal";
203 __XNU_PRIVATE_EXTERN char drivercorefilename[MAXPATHLEN + 1] = {"/private/var/internal/%N.core"};
204 #elif defined(XNU_TARGET_OS_OSX)
205 __XNU_PRIVATE_EXTERN const char * defaultcorefiledir = "/cores";
206 __XNU_PRIVATE_EXTERN char corefilename[MAXPATHLEN + 1] = {"/cores/core.%P"};
207 __XNU_PRIVATE_EXTERN const char * defaultdrivercorefiledir = "/private/var/dextcores";
208 __XNU_PRIVATE_EXTERN char drivercorefilename[MAXPATHLEN + 1] = {"/private/var/dextcores/%N.core"};
209 #else
210 __XNU_PRIVATE_EXTERN const char * defaultcorefiledir = "/private/var/cores";
211 __XNU_PRIVATE_EXTERN char corefilename[MAXPATHLEN + 1] = {"/private/var/cores/%N.core"};
212 __XNU_PRIVATE_EXTERN const char * defaultdrivercorefiledir = "/private/var/dextcores";
213 __XNU_PRIVATE_EXTERN char drivercorefilename[MAXPATHLEN + 1] = {"/private/var/dextcores/%N.core"};
214 #endif
215 #endif
216 
217 #if PROC_REF_DEBUG
218 #include <kern/backtrace.h>
219 #endif
220 
221 static LCK_MTX_DECLARE_ATTR(proc_klist_mlock, &proc_mlock_grp, &proc_lck_attr);
222 
223 ZONE_DEFINE(pgrp_zone, "pgrp",
224     sizeof(struct pgrp), ZC_ZFREE_CLEARMEM);
225 ZONE_DEFINE(session_zone, "session",
226     sizeof(struct session), ZC_ZFREE_CLEARMEM);
227 ZONE_DEFINE_ID(ZONE_ID_PROC_RO, "proc_ro", struct proc_ro,
228     ZC_READONLY | ZC_ZFREE_CLEARMEM);
229 
230 typedef uint64_t unaligned_u64 __attribute__((aligned(1)));
231 
232 static void orphanpg(struct pgrp * pg);
233 void proc_name_kdp(proc_t t, char * buf, int size);
234 boolean_t proc_binary_uuid_kdp(task_t task, uuid_t uuid);
235 boolean_t current_thread_aborted(void);
236 int proc_threadname_kdp(void * uth, char * buf, size_t size);
237 void proc_starttime_kdp(void * p, unaligned_u64 *tv_sec, unaligned_u64 *tv_usec, unaligned_u64 *abstime);
238 void proc_archinfo_kdp(void* p, cpu_type_t* cputype, cpu_subtype_t* cpusubtype);
239 uint64_t proc_getcsflags_kdp(void * p);
240 const char * proc_name_address(void * p);
241 char * proc_longname_address(void *);
242 
243 static void pgrp_destroy(struct pgrp *pgrp);
244 static void pgrp_replace(proc_t p, struct pgrp *pgrp);
245 static int csops_internal(pid_t pid, int ops, user_addr_t uaddr, user_size_t usersize, user_addr_t uaddittoken);
246 static boolean_t proc_parent_is_currentproc(proc_t p);
247 
248 #if CONFIG_PROC_RESOURCE_LIMITS
249 extern void task_filedesc_ast(task_t task, int current_size, int soft_limit, int hard_limit);
250 extern void task_kqworkloop_ast(task_t task, int current_size, int soft_limit, int hard_limit);
251 #endif
252 
253 /* defined in bsd/kern/kern_prot.c */
254 extern int get_audit_token_pid(const audit_token_t *audit_token);
255 
256 struct fixjob_iterargs {
257 	struct pgrp * pg;
258 	struct session * mysession;
259 	int entering;
260 };
261 
262 int fixjob_callback(proc_t, void *);
263 
264 uint64_t
get_current_unique_pid(void)265 get_current_unique_pid(void)
266 {
267 	proc_t  p = current_proc();
268 
269 	if (p) {
270 		return proc_uniqueid(p);
271 	} else {
272 		return 0;
273 	}
274 }
275 
276 /*
277  * Initialize global process hashing structures.
278  */
279 static void
procinit(void)280 procinit(void)
281 {
282 	smr_hash_init(&pid_hash, maxproc / 4);
283 	smr_hash_init(&pgrp_hash, maxproc / 4);
284 	sesshashtbl = hashinit(maxproc / 4, M_PROC, &sesshash);
285 	uihashtbl = hashinit(maxproc / 16, M_PROC, &uihash);
286 }
287 STARTUP(EARLY_BOOT, STARTUP_RANK_FIRST, procinit);
288 
289 /*
290  * Change the count associated with number of processes
291  * a given user is using. This routine protects the uihash
292  * with the list lock
293  */
294 size_t
chgproccnt(uid_t uid,int diff)295 chgproccnt(uid_t uid, int diff)
296 {
297 	struct uidinfo *uip;
298 	struct uidinfo *newuip = NULL;
299 	struct uihashhead *uipp;
300 	size_t retval;
301 
302 again:
303 	proc_list_lock();
304 	uipp = UIHASH(uid);
305 	for (uip = uipp->lh_first; uip != 0; uip = uip->ui_hash.le_next) {
306 		if (uip->ui_uid == uid) {
307 			break;
308 		}
309 	}
310 	if (uip) {
311 		uip->ui_proccnt += diff;
312 		if (uip->ui_proccnt > 0) {
313 			retval = uip->ui_proccnt;
314 			proc_list_unlock();
315 			goto out;
316 		}
317 		LIST_REMOVE(uip, ui_hash);
318 		retval = 0;
319 		proc_list_unlock();
320 		kfree_type(struct uidinfo, uip);
321 		goto out;
322 	}
323 	if (diff <= 0) {
324 		if (diff == 0) {
325 			retval = 0;
326 			proc_list_unlock();
327 			goto out;
328 		}
329 		panic("chgproccnt: lost user");
330 	}
331 	if (newuip != NULL) {
332 		uip = newuip;
333 		newuip = NULL;
334 		LIST_INSERT_HEAD(uipp, uip, ui_hash);
335 		uip->ui_uid = uid;
336 		uip->ui_proccnt = diff;
337 		retval = diff;
338 		proc_list_unlock();
339 		goto out;
340 	}
341 	proc_list_unlock();
342 	newuip = kalloc_type(struct uidinfo, Z_WAITOK | Z_NOFAIL);
343 	goto again;
344 out:
345 	kfree_type(struct uidinfo, newuip);
346 	return retval;
347 }
348 
349 /*
350  * Is p an inferior of the current process?
351  */
352 int
inferior(proc_t p)353 inferior(proc_t p)
354 {
355 	int retval = 0;
356 
357 	proc_list_lock();
358 	for (; p != current_proc(); p = p->p_pptr) {
359 		if (proc_getpid(p) == 0) {
360 			goto out;
361 		}
362 	}
363 	retval = 1;
364 out:
365 	proc_list_unlock();
366 	return retval;
367 }
368 
369 /*
370  * Is p an inferior of t ?
371  */
372 int
isinferior(proc_t p,proc_t t)373 isinferior(proc_t p, proc_t t)
374 {
375 	int retval = 0;
376 	int nchecked = 0;
377 	proc_t start = p;
378 
379 	/* if p==t they are not inferior */
380 	if (p == t) {
381 		return 0;
382 	}
383 
384 	proc_list_lock();
385 	for (; p != t; p = p->p_pptr) {
386 		nchecked++;
387 
388 		/* Detect here if we're in a cycle */
389 		if ((proc_getpid(p) == 0) || (p->p_pptr == start) || (nchecked >= nprocs)) {
390 			goto out;
391 		}
392 	}
393 	retval = 1;
394 out:
395 	proc_list_unlock();
396 	return retval;
397 }
398 
399 int
proc_isinferior(int pid1,int pid2)400 proc_isinferior(int pid1, int pid2)
401 {
402 	proc_t p = PROC_NULL;
403 	proc_t t = PROC_NULL;
404 	int retval = 0;
405 
406 	if (((p = proc_find(pid1)) != (proc_t)0) && ((t = proc_find(pid2)) != (proc_t)0)) {
407 		retval = isinferior(p, t);
408 	}
409 
410 	if (p != PROC_NULL) {
411 		proc_rele(p);
412 	}
413 	if (t != PROC_NULL) {
414 		proc_rele(t);
415 	}
416 
417 	return retval;
418 }
419 
420 /*
421  * Returns process identity of a given process. Calling this function is not
422  * racy for a current process or if a reference to the process is held.
423  */
424 struct proc_ident
proc_ident(proc_t p)425 proc_ident(proc_t p)
426 {
427 	struct proc_ident ident = {
428 		.p_pid = proc_pid(p),
429 		.p_uniqueid = proc_uniqueid(p),
430 		.p_idversion = proc_pidversion(p),
431 	};
432 
433 	return ident;
434 }
435 
436 proc_t
proc_find_audit_token(const audit_token_t token)437 proc_find_audit_token(const audit_token_t token)
438 {
439 	proc_t proc = PROC_NULL;
440 
441 	pid_t pid = get_audit_token_pid(&token);
442 	if (pid <= 0) {
443 		return PROC_NULL;
444 	}
445 
446 	if ((proc = proc_find(pid)) == PROC_NULL) {
447 		return PROC_NULL;
448 	}
449 
450 	/* Check the target proc pidversion */
451 	int pidversion = proc_pidversion(proc);
452 	if (pidversion != token.val[7]) {
453 		proc_rele(proc);
454 		return PROC_NULL;
455 	}
456 
457 	return proc;
458 }
459 
460 proc_t
proc_find_ident(struct proc_ident const * ident)461 proc_find_ident(struct proc_ident const *ident)
462 {
463 	proc_t proc = PROC_NULL;
464 
465 	proc = proc_find(ident->p_pid);
466 	if (proc == PROC_NULL) {
467 		return PROC_NULL;
468 	}
469 
470 	if (proc_uniqueid(proc) != ident->p_uniqueid ||
471 	    proc_pidversion(proc) != ident->p_idversion) {
472 		proc_rele(proc);
473 		return PROC_NULL;
474 	}
475 
476 	return proc;
477 }
478 
479 void
uthread_reset_proc_refcount(uthread_t uth)480 uthread_reset_proc_refcount(uthread_t uth)
481 {
482 	uth->uu_proc_refcount = 0;
483 
484 #if PROC_REF_DEBUG
485 	if (kern_feature_override(KF_DISABLE_PROCREF_TRACKING_OVRD)) {
486 		return;
487 	}
488 
489 	struct uthread_proc_ref_info *upri = uth->uu_proc_ref_info;
490 	uint32_t n = uth->uu_proc_ref_info->upri_pindex;
491 
492 	uth->uu_proc_ref_info->upri_pindex = 0;
493 
494 	if (n) {
495 		for (unsigned i = 0; i < n; i++) {
496 			btref_put(upri->upri_proc_stacks[i]);
497 		}
498 		bzero(upri->upri_proc_stacks, sizeof(btref_t) * n);
499 		bzero(upri->upri_proc_ps, sizeof(proc_t) * n);
500 	}
501 #endif /* PROC_REF_DEBUG */
502 }
503 
504 #if PROC_REF_DEBUG
505 void
uthread_init_proc_refcount(uthread_t uth)506 uthread_init_proc_refcount(uthread_t uth)
507 {
508 	if (kern_feature_override(KF_DISABLE_PROCREF_TRACKING_OVRD)) {
509 		return;
510 	}
511 
512 	uth->uu_proc_ref_info = kalloc_type(struct uthread_proc_ref_info,
513 	    Z_ZERO | Z_WAITOK | Z_NOFAIL);
514 }
515 
516 void
uthread_destroy_proc_refcount(uthread_t uth)517 uthread_destroy_proc_refcount(uthread_t uth)
518 {
519 	if (kern_feature_override(KF_DISABLE_PROCREF_TRACKING_OVRD)) {
520 		return;
521 	}
522 
523 	struct uthread_proc_ref_info *upri = uth->uu_proc_ref_info;
524 	uint32_t n = uth->uu_proc_ref_info->upri_pindex;
525 
526 	for (unsigned i = 0; i < n; i++) {
527 		btref_put(upri->upri_proc_stacks[i]);
528 	}
529 
530 	kfree_type(struct uthread_proc_ref_info, uth->uu_proc_ref_info);
531 }
532 
533 void
uthread_assert_zero_proc_refcount(uthread_t uth)534 uthread_assert_zero_proc_refcount(uthread_t uth)
535 {
536 	if (kern_feature_override(KF_DISABLE_PROCREF_TRACKING_OVRD)) {
537 		return;
538 	}
539 
540 	if (__improbable(uth->uu_proc_refcount != 0)) {
541 		panic("Unexpected non zero uu_proc_refcount = %d (%p)",
542 		    uth->uu_proc_refcount, uth);
543 	}
544 }
545 #endif /* PROC_REF_DEBUG */
546 
547 bool
proc_list_exited(proc_t p)548 proc_list_exited(proc_t p)
549 {
550 	return os_ref_get_raw_mask(&p->p_refcount) & P_REF_DEAD;
551 }
552 
553 #if CONFIG_DEBUG_SYSCALL_REJECTION
554 uint64_t
uthread_get_syscall_rejection_flags(void * uthread)555 uthread_get_syscall_rejection_flags(void *uthread)
556 {
557 	uthread_t uth = (uthread_t) uthread;
558 	return uth->syscall_rejection_flags;
559 }
560 
561 uint64_t*
uthread_get_syscall_rejection_mask(void * uthread)562 uthread_get_syscall_rejection_mask(void *uthread)
563 {
564 	uthread_t uth = (uthread_t) uthread;
565 	return uth->syscall_rejection_mask;
566 }
567 
568 uint64_t*
uthread_get_syscall_rejection_once_mask(void * uthread)569 uthread_get_syscall_rejection_once_mask(void *uthread)
570 {
571 	uthread_t uth = (uthread_t) uthread;
572 	return uth->syscall_rejection_once_mask;
573 }
574 
575 bool
uthread_syscall_rejection_is_enabled(void * uthread)576 uthread_syscall_rejection_is_enabled(void *uthread)
577 {
578 	uthread_t uth = (uthread_t) uthread;
579 	return (debug_syscall_rejection_mode != 0) || (uth->syscall_rejection_flags & SYSCALL_REJECTION_FLAGS_FORCE_FATAL);
580 }
581 #endif /* CONFIG_DEBUG_SYSCALL_REJECTION */
582 
583 #if PROC_REF_DEBUG
584 __attribute__((noinline))
585 #endif /* PROC_REF_DEBUG */
586 static void
record_procref(proc_t p __unused,int count)587 record_procref(proc_t p __unused, int count)
588 {
589 	uthread_t uth;
590 
591 	uth = current_uthread();
592 	uth->uu_proc_refcount += count;
593 
594 #if PROC_REF_DEBUG
595 	if (kern_feature_override(KF_DISABLE_PROCREF_TRACKING_OVRD)) {
596 		return;
597 	}
598 	struct uthread_proc_ref_info *upri = uth->uu_proc_ref_info;
599 
600 	if (upri->upri_pindex < NUM_PROC_REFS_TO_TRACK) {
601 		upri->upri_proc_stacks[upri->upri_pindex] =
602 		    btref_get(__builtin_frame_address(0), BTREF_GET_NOWAIT);
603 		upri->upri_proc_ps[upri->upri_pindex] = p;
604 		upri->upri_pindex++;
605 	}
606 #endif /* PROC_REF_DEBUG */
607 }
608 
609 /*!
610  * @function proc_ref_try_fast()
611  *
612  * @brief
613  * Tries to take a proc ref, unless it is in flux (being made, or dead).
614  *
615  * @returns
616  * - the new refcount value (including bits) on success,
617  * - 0 on failure.
618  */
619 static inline uint32_t
proc_ref_try_fast(proc_t p)620 proc_ref_try_fast(proc_t p)
621 {
622 	uint32_t bits;
623 
624 	proc_require(p, PROC_REQUIRE_ALLOW_ALL);
625 
626 	bits = os_ref_retain_try_mask(&p->p_refcount, P_REF_BITS,
627 	    P_REF_NEW | P_REF_DEAD, NULL);
628 	if (bits) {
629 		record_procref(p, 1);
630 	}
631 	return bits;
632 }
633 
634 /*!
635  * @function proc_ref_wait()
636  *
637  * @brief
638  * Waits for the specified bits to clear, on the specified event.
639  */
640 __attribute__((noinline))
641 static void
proc_ref_wait(proc_t p,event_t event,proc_ref_bits_t mask,bool locked)642 proc_ref_wait(proc_t p, event_t event, proc_ref_bits_t mask, bool locked)
643 {
644 	assert_wait(event, THREAD_UNINT | THREAD_WAIT_NOREPORT);
645 
646 	if (os_ref_get_raw_mask(&p->p_refcount) & mask) {
647 		uthread_t uth = current_uthread();
648 
649 		if (locked) {
650 			proc_list_unlock();
651 		}
652 		uth->uu_wchan = event;
653 		uth->uu_wmesg = "proc_refwait";
654 		thread_block(THREAD_CONTINUE_NULL);
655 		uth->uu_wchan = NULL;
656 		uth->uu_wmesg = NULL;
657 		if (locked) {
658 			proc_list_lock();
659 		}
660 	} else {
661 		clear_wait(current_thread(), THREAD_AWAKENED);
662 	}
663 }
664 
665 /*!
666  * @function proc_ref_wait_for_exec()
667  *
668  * @brief
669  * Routine called by processes trying to acquire a ref while
670  * an exec is in flight.
671  *
672  * @discussion
673  * This function is called with a proc ref held on the proc,
674  * which will be given up until the @c P_REF_*_EXEC flags clear.
675  *
676  * @param p       the proc, the caller owns a proc ref
677  * @param bits    the result of @c proc_ref_try_fast() prior to calling this.
678  * @param locked  whether the caller holds the @c proc_list_lock().
679  */
680 __attribute__((noinline))
681 static proc_t
proc_ref_wait_for_exec(proc_t p,uint32_t bits,int locked)682 proc_ref_wait_for_exec(proc_t p, uint32_t bits, int locked)
683 {
684 	const proc_ref_bits_t mask = P_REF_WILL_EXEC | P_REF_IN_EXEC;
685 
686 	/*
687 	 * the proc is in the middle of exec,
688 	 * trade our ref for a "wait ref",
689 	 * and wait for the proc_refwake_did_exec() call.
690 	 *
691 	 * Note: it's very unlikely that we'd loop back into the wait,
692 	 *       it would only happen if the target proc would be
693 	 *       in exec again by the time we woke up.
694 	 */
695 	os_ref_retain_raw(&p->p_waitref, &p_refgrp);
696 
697 	do {
698 		proc_rele(p);
699 		proc_ref_wait(p, &p->p_waitref, mask, locked);
700 		bits = proc_ref_try_fast(p);
701 	} while (__improbable(bits & mask));
702 
703 	proc_wait_release(p);
704 
705 	return bits ? p : PROC_NULL;
706 }
707 
708 static inline bool
proc_ref_needs_wait_for_exec(uint32_t bits)709 proc_ref_needs_wait_for_exec(uint32_t bits)
710 {
711 	if (__probable((bits & (P_REF_WILL_EXEC | P_REF_IN_EXEC)) == 0)) {
712 		return false;
713 	}
714 
715 	if (bits & P_REF_IN_EXEC) {
716 		return true;
717 	}
718 
719 	/*
720 	 * procs can't have outstanding refs while execing.
721 	 *
722 	 * In order to achieve, that, proc_refdrain_will_exec()
723 	 * will drain outstanding references. It signals its intent
724 	 * with the P_REF_WILL_EXEC flag, and moves to P_REF_IN_EXEC
725 	 * when this is achieved.
726 	 *
727 	 * Most threads will block in proc_ref() when any of those
728 	 * flags is set. However, threads that already have
729 	 * an oustanding ref on this proc might want another
730 	 * before dropping them. To avoid deadlocks, we need
731 	 * to let threads with any oustanding reference take one
732 	 * when only P_REF_WILL_EXEC is set (which causes exec
733 	 * to be delayed).
734 	 *
735 	 * Note: the current thread will _always_ appear like it holds
736 	 *       one ref due to having taken one speculatively.
737 	 */
738 	assert(current_uthread()->uu_proc_refcount >= 1);
739 	return current_uthread()->uu_proc_refcount == 1;
740 }
741 
742 int
proc_rele(proc_t p)743 proc_rele(proc_t p)
744 {
745 	uint32_t o_bits, n_bits;
746 
747 	proc_require(p, PROC_REQUIRE_ALLOW_ALL);
748 
749 	os_atomic_rmw_loop(&p->p_refcount, o_bits, n_bits, release, {
750 		n_bits = o_bits - (1u << P_REF_BITS);
751 		if ((n_bits >> P_REF_BITS) == 1) {
752 		        n_bits &= ~P_REF_DRAINING;
753 		}
754 	});
755 	record_procref(p, -1);
756 
757 	/*
758 	 * p might be freed after this point.
759 	 */
760 
761 	if (__improbable((o_bits & P_REF_DRAINING) && !(n_bits & P_REF_DRAINING))) {
762 		/*
763 		 * This wakeup can cause spurious ones,
764 		 * but proc_refdrain() can deal with those.
765 		 *
766 		 * Because the proc_zone memory is sequestered,
767 		 * this is safe to wakeup a possible "freed" address.
768 		 */
769 		wakeup(&p->p_refcount);
770 	}
771 	return 0;
772 }
773 
774 bool
proc_is_shadow(proc_t p)775 proc_is_shadow(proc_t p)
776 {
777 	return os_ref_get_raw_mask(&p->p_refcount) & P_REF_SHADOW;
778 }
779 
780 proc_t
proc_self(void)781 proc_self(void)
782 {
783 	proc_t p = current_proc();
784 
785 	/*
786 	 * Do not go through the logic of "wait for exec", it is meaningless.
787 	 * Only fail taking a ref for oneself if the proc is about to die.
788 	 */
789 	return proc_ref_try_fast(p) ? p : PROC_NULL;
790 }
791 
792 proc_t
proc_ref(proc_t p,int locked)793 proc_ref(proc_t p, int locked)
794 {
795 	uint32_t bits;
796 
797 	bits = proc_ref_try_fast(p);
798 	if (__improbable(!bits)) {
799 		return PROC_NULL;
800 	}
801 
802 	if (__improbable(proc_ref_needs_wait_for_exec(bits))) {
803 		return proc_ref_wait_for_exec(p, bits, locked);
804 	}
805 
806 	return p;
807 }
808 
809 static void
proc_wait_free(smr_node_t node)810 proc_wait_free(smr_node_t node)
811 {
812 	struct proc *p = __container_of(node, struct proc, p_smr_node);
813 
814 	proc_release_proc_task_struct(p);
815 }
816 
817 void
proc_wait_release(proc_t p)818 proc_wait_release(proc_t p)
819 {
820 	if (__probable(os_ref_release_raw(&p->p_waitref, &p_refgrp) == 0)) {
821 		smr_proc_task_call(&p->p_smr_node, proc_and_task_size,
822 		    proc_wait_free);
823 	}
824 }
825 
826 proc_t
proc_find_zombref(int pid)827 proc_find_zombref(int pid)
828 {
829 	proc_t p;
830 
831 	proc_list_lock();
832 	p = proc_find_zombref_locked(pid);
833 	proc_list_unlock();
834 
835 	return p;
836 }
837 
838 proc_t
proc_find_zombref_locked(int pid)839 proc_find_zombref_locked(int pid)
840 {
841 	proc_t p;
842 
843 	LCK_MTX_ASSERT(&proc_list_mlock, LCK_MTX_ASSERT_OWNED);
844 
845 again:
846 	p = phash_find_locked(pid);
847 
848 	/* should we bail? */
849 	if ((p == PROC_NULL) || !proc_list_exited(p)) {
850 		return PROC_NULL;
851 	}
852 
853 	/* If someone else is controlling the (unreaped) zombie - wait */
854 	if ((p->p_listflag & P_LIST_WAITING) != 0) {
855 		(void)msleep(&p->p_stat, &proc_list_mlock, PWAIT, "waitcoll", 0);
856 		goto again;
857 	}
858 	p->p_listflag |=  P_LIST_WAITING;
859 
860 	return p;
861 }
862 
863 void
proc_drop_zombref(proc_t p)864 proc_drop_zombref(proc_t p)
865 {
866 	proc_list_lock();
867 	if ((p->p_listflag & P_LIST_WAITING) == P_LIST_WAITING) {
868 		p->p_listflag &= ~P_LIST_WAITING;
869 		wakeup(&p->p_stat);
870 	}
871 	proc_list_unlock();
872 }
873 
874 
875 void
proc_refdrain(proc_t p)876 proc_refdrain(proc_t p)
877 {
878 	uint32_t bits = os_ref_get_raw_mask(&p->p_refcount);
879 
880 	assert(proc_list_exited(p));
881 
882 	while ((bits >> P_REF_BITS) > 1) {
883 		if (os_atomic_cmpxchgv(&p->p_refcount, bits,
884 		    bits | P_REF_DRAINING, &bits, relaxed)) {
885 			proc_ref_wait(p, &p->p_refcount, P_REF_DRAINING, false);
886 		}
887 	}
888 }
889 
890 proc_t
proc_refdrain_will_exec(proc_t p)891 proc_refdrain_will_exec(proc_t p)
892 {
893 	const proc_ref_bits_t will_exec_mask = P_REF_WILL_EXEC | P_REF_DRAINING;
894 
895 	/*
896 	 * All the calls to proc_ref will wait
897 	 * for the flag to get cleared before returning a ref.
898 	 *
899 	 * (except for the case documented in proc_ref_needs_wait_for_exec()).
900 	 */
901 
902 	if (p == initproc) {
903 		/* Do not wait in ref drain for launchd exec */
904 		os_atomic_or(&p->p_refcount, P_REF_IN_EXEC, relaxed);
905 	} else {
906 		for (;;) {
907 			uint32_t o_ref, n_ref;
908 
909 			os_atomic_rmw_loop(&p->p_refcount, o_ref, n_ref, relaxed, {
910 				if ((o_ref >> P_REF_BITS) == 1) {
911 				        /*
912 				         * We drained successfully,
913 				         * move on to P_REF_IN_EXEC
914 				         */
915 				        n_ref = o_ref & ~will_exec_mask;
916 				        n_ref |= P_REF_IN_EXEC;
917 				} else {
918 				        /*
919 				         * Outstanding refs exit,
920 				         * mark our desire to stall
921 				         * proc_ref() callers with
922 				         * P_REF_WILL_EXEC.
923 				         */
924 				        n_ref = o_ref | will_exec_mask;
925 				}
926 			});
927 
928 			if (n_ref & P_REF_IN_EXEC) {
929 				break;
930 			}
931 
932 			proc_ref_wait(p, &p->p_refcount, P_REF_DRAINING, false);
933 		}
934 	}
935 
936 	/* Return a ref to the caller */
937 	os_ref_retain_mask(&p->p_refcount, P_REF_BITS, NULL);
938 	record_procref(p, 1);
939 
940 	return p;
941 }
942 
943 void
proc_refwake_did_exec(proc_t p)944 proc_refwake_did_exec(proc_t p)
945 {
946 	os_atomic_andnot(&p->p_refcount, P_REF_IN_EXEC, release);
947 	wakeup(&p->p_waitref);
948 }
949 
950 void
proc_ref_hold_proc_task_struct(proc_t proc)951 proc_ref_hold_proc_task_struct(proc_t proc)
952 {
953 	os_atomic_or(&proc->p_refcount, P_REF_PROC_HOLD, relaxed);
954 }
955 
956 static void
proc_free(proc_t proc,proc_ro_t proc_ro)957 proc_free(proc_t proc, proc_ro_t proc_ro)
958 {
959 	kauth_cred_t cred;
960 
961 	assert(proc_ro != NULL);
962 
963 	cred = smr_serialized_load(&proc_ro->p_ucred);
964 	kauth_cred_set(&cred, NOCRED);
965 
966 	zfree_ro(ZONE_ID_PROC_RO, proc_ro);
967 
968 	zfree(proc_task_zone, proc);
969 }
970 
971 void
proc_release_proc_task_struct(proc_t proc)972 proc_release_proc_task_struct(proc_t proc)
973 {
974 	uint32_t old_ref = os_atomic_andnot_orig(&proc->p_refcount, P_REF_PROC_HOLD, relaxed);
975 	if ((old_ref & P_REF_TASK_HOLD) == 0) {
976 		proc_free(proc, proc->p_proc_ro);
977 	}
978 }
979 
980 void
task_ref_hold_proc_task_struct(task_t task)981 task_ref_hold_proc_task_struct(task_t task)
982 {
983 	proc_t proc_from_task = task_get_proc_raw(task);
984 	os_atomic_or(&proc_from_task->p_refcount, P_REF_TASK_HOLD, relaxed);
985 }
986 
987 void
task_release_proc_task_struct(task_t task,proc_ro_t proc_ro)988 task_release_proc_task_struct(task_t task, proc_ro_t proc_ro)
989 {
990 	proc_t proc_from_task = task_get_proc_raw(task);
991 	uint32_t old_ref = os_atomic_andnot_orig(&proc_from_task->p_refcount, P_REF_TASK_HOLD, relaxed);
992 
993 	if ((old_ref & P_REF_PROC_HOLD) == 0) {
994 		proc_free(proc_from_task, proc_ro);
995 	}
996 }
997 
998 proc_t
proc_parentholdref(proc_t p)999 proc_parentholdref(proc_t p)
1000 {
1001 	proc_t parent = PROC_NULL;
1002 	proc_t pp;
1003 
1004 	proc_list_lock();
1005 loop:
1006 	pp = p->p_pptr;
1007 	if ((pp == PROC_NULL) || (pp->p_stat == SZOMB) || ((pp->p_listflag & (P_LIST_CHILDDRSTART | P_LIST_CHILDDRAINED)) == (P_LIST_CHILDDRSTART | P_LIST_CHILDDRAINED))) {
1008 		parent = PROC_NULL;
1009 		goto out;
1010 	}
1011 
1012 	if ((pp->p_listflag & (P_LIST_CHILDDRSTART | P_LIST_CHILDDRAINED)) == P_LIST_CHILDDRSTART) {
1013 		pp->p_listflag |= P_LIST_CHILDDRWAIT;
1014 		msleep(&pp->p_childrencnt, &proc_list_mlock, 0, "proc_parent", 0);
1015 		goto loop;
1016 	}
1017 
1018 	if ((pp->p_listflag & (P_LIST_CHILDDRSTART | P_LIST_CHILDDRAINED)) == 0) {
1019 		pp->p_parentref++;
1020 		parent = pp;
1021 		goto out;
1022 	}
1023 
1024 out:
1025 	proc_list_unlock();
1026 	return parent;
1027 }
1028 int
proc_parentdropref(proc_t p,int listlocked)1029 proc_parentdropref(proc_t p, int listlocked)
1030 {
1031 	if (listlocked == 0) {
1032 		proc_list_lock();
1033 	}
1034 
1035 	if (p->p_parentref > 0) {
1036 		p->p_parentref--;
1037 		if ((p->p_parentref == 0) && ((p->p_listflag & P_LIST_PARENTREFWAIT) == P_LIST_PARENTREFWAIT)) {
1038 			p->p_listflag &= ~P_LIST_PARENTREFWAIT;
1039 			wakeup(&p->p_parentref);
1040 		}
1041 	} else {
1042 		panic("proc_parentdropref  -ve ref");
1043 	}
1044 	if (listlocked == 0) {
1045 		proc_list_unlock();
1046 	}
1047 
1048 	return 0;
1049 }
1050 
1051 void
proc_childdrainstart(proc_t p)1052 proc_childdrainstart(proc_t p)
1053 {
1054 #if __PROC_INTERNAL_DEBUG
1055 	if ((p->p_listflag & P_LIST_CHILDDRSTART) == P_LIST_CHILDDRSTART) {
1056 		panic("proc_childdrainstart: childdrain already started");
1057 	}
1058 #endif
1059 	p->p_listflag |= P_LIST_CHILDDRSTART;
1060 	/* wait for all that hold parentrefs to drop */
1061 	while (p->p_parentref > 0) {
1062 		p->p_listflag |= P_LIST_PARENTREFWAIT;
1063 		msleep(&p->p_parentref, &proc_list_mlock, 0, "proc_childdrainstart", 0);
1064 	}
1065 }
1066 
1067 
1068 void
proc_childdrainend(proc_t p)1069 proc_childdrainend(proc_t p)
1070 {
1071 #if __PROC_INTERNAL_DEBUG
1072 	if (p->p_childrencnt > 0) {
1073 		panic("exiting: children stil hanging around");
1074 	}
1075 #endif
1076 	p->p_listflag |= P_LIST_CHILDDRAINED;
1077 	if ((p->p_listflag & (P_LIST_CHILDLKWAIT | P_LIST_CHILDDRWAIT)) != 0) {
1078 		p->p_listflag &= ~(P_LIST_CHILDLKWAIT | P_LIST_CHILDDRWAIT);
1079 		wakeup(&p->p_childrencnt);
1080 	}
1081 }
1082 
1083 void
proc_checkdeadrefs(__unused proc_t p)1084 proc_checkdeadrefs(__unused proc_t p)
1085 {
1086 	uint32_t bits;
1087 
1088 	bits = os_ref_release_raw_mask(&p->p_refcount, P_REF_BITS, NULL);
1089 	bits &= ~(P_REF_SHADOW | P_REF_PROC_HOLD | P_REF_TASK_HOLD);
1090 	if (bits != P_REF_DEAD) {
1091 		panic("proc being freed and unexpected refcount %p:%d:0x%x", p,
1092 		    bits >> P_REF_BITS, bits & P_REF_MASK);
1093 	}
1094 #if __PROC_INTERNAL_DEBUG
1095 	if (p->p_childrencnt != 0) {
1096 		panic("proc being freed and pending children cnt %p:%d", p, p->p_childrencnt);
1097 	}
1098 	if (p->p_parentref != 0) {
1099 		panic("proc being freed and pending parentrefs %p:%d", p, p->p_parentref);
1100 	}
1101 #endif
1102 }
1103 
1104 
1105 __attribute__((always_inline, visibility("hidden")))
1106 void
proc_require(proc_t proc,proc_require_flags_t flags)1107 proc_require(proc_t proc, proc_require_flags_t flags)
1108 {
1109 	if ((flags & PROC_REQUIRE_ALLOW_NULL) && proc == PROC_NULL) {
1110 		return;
1111 	}
1112 	zone_id_require(ZONE_ID_PROC_TASK, proc_and_task_size, proc);
1113 }
1114 
1115 pid_t
proc_getpid(proc_t p)1116 proc_getpid(proc_t p)
1117 {
1118 	if (p == kernproc) {
1119 		return 0;
1120 	}
1121 
1122 	return p->p_pid;
1123 }
1124 
1125 int
proc_pid(proc_t p)1126 proc_pid(proc_t p)
1127 {
1128 	if (p != NULL) {
1129 		proc_require(p, PROC_REQUIRE_ALLOW_ALL);
1130 		return proc_getpid(p);
1131 	}
1132 	return -1;
1133 }
1134 
1135 int
proc_ppid(proc_t p)1136 proc_ppid(proc_t p)
1137 {
1138 	if (p != NULL) {
1139 		proc_require(p, PROC_REQUIRE_ALLOW_ALL);
1140 		return p->p_ppid;
1141 	}
1142 	return -1;
1143 }
1144 
1145 int
proc_original_ppid(proc_t p)1146 proc_original_ppid(proc_t p)
1147 {
1148 	if (p != NULL) {
1149 		proc_require(p, PROC_REQUIRE_ALLOW_ALL);
1150 		return proc_get_ro(p)->p_orig_ppid;
1151 	}
1152 	return -1;
1153 }
1154 
1155 int
proc_orig_ppidversion(proc_t p)1156 proc_orig_ppidversion(proc_t p)
1157 {
1158 	if (p != NULL) {
1159 		proc_require(p, PROC_REQUIRE_ALLOW_ALL);
1160 		return proc_get_ro(p)->p_orig_ppidversion;
1161 	}
1162 	return -1;
1163 }
1164 
1165 int
proc_starttime(proc_t p,struct timeval * tv)1166 proc_starttime(proc_t p, struct timeval *tv)
1167 {
1168 	if (p != NULL && tv != NULL) {
1169 		tv->tv_sec = p->p_start.tv_sec;
1170 		tv->tv_usec = p->p_start.tv_usec;
1171 		return 0;
1172 	}
1173 	return EINVAL;
1174 }
1175 
1176 int
proc_selfpid(void)1177 proc_selfpid(void)
1178 {
1179 	return proc_getpid(current_proc());
1180 }
1181 
1182 int
proc_selfppid(void)1183 proc_selfppid(void)
1184 {
1185 	return current_proc()->p_ppid;
1186 }
1187 
1188 uint64_t
proc_selfcsflags(void)1189 proc_selfcsflags(void)
1190 {
1191 	return proc_getcsflags(current_proc());
1192 }
1193 
1194 int
proc_csflags(proc_t p,uint64_t * flags)1195 proc_csflags(proc_t p, uint64_t *flags)
1196 {
1197 	if (p && flags) {
1198 		proc_require(p, PROC_REQUIRE_ALLOW_ALL);
1199 		*flags = proc_getcsflags(p);
1200 		return 0;
1201 	}
1202 	return EINVAL;
1203 }
1204 
1205 boolean_t
proc_is_simulated(const proc_t p)1206 proc_is_simulated(const proc_t p)
1207 {
1208 #ifdef XNU_TARGET_OS_OSX
1209 	if (p != NULL) {
1210 		switch (proc_platform(p)) {
1211 		case PLATFORM_IOSSIMULATOR:
1212 		case PLATFORM_TVOSSIMULATOR:
1213 		case PLATFORM_WATCHOSSIMULATOR:
1214 			return TRUE;
1215 		default:
1216 			return FALSE;
1217 		}
1218 	}
1219 #else /* !XNU_TARGET_OS_OSX */
1220 	(void)p;
1221 #endif
1222 	return FALSE;
1223 }
1224 
1225 uint32_t
proc_platform(const proc_t p)1226 proc_platform(const proc_t p)
1227 {
1228 	if (p != NULL) {
1229 		return proc_get_ro(p)->p_platform_data.p_platform;
1230 	}
1231 	return (uint32_t)-1;
1232 }
1233 
1234 uint32_t
proc_min_sdk(proc_t p)1235 proc_min_sdk(proc_t p)
1236 {
1237 	if (p != NULL) {
1238 		return proc_get_ro(p)->p_platform_data.p_min_sdk;
1239 	}
1240 	return (uint32_t)-1;
1241 }
1242 
1243 uint32_t
proc_sdk(proc_t p)1244 proc_sdk(proc_t p)
1245 {
1246 	if (p != NULL) {
1247 		return proc_get_ro(p)->p_platform_data.p_sdk;
1248 	}
1249 	return (uint32_t)-1;
1250 }
1251 
1252 void
proc_setplatformdata(proc_t p,uint32_t platform,uint32_t min_sdk,uint32_t sdk)1253 proc_setplatformdata(proc_t p, uint32_t platform, uint32_t min_sdk, uint32_t sdk)
1254 {
1255 	proc_ro_t ro;
1256 	struct proc_platform_ro_data platform_data;
1257 
1258 	ro = proc_get_ro(p);
1259 	platform_data = ro->p_platform_data;
1260 	platform_data.p_platform = platform;
1261 	platform_data.p_min_sdk = min_sdk;
1262 	platform_data.p_sdk = sdk;
1263 
1264 	zalloc_ro_update_field(ZONE_ID_PROC_RO, ro, p_platform_data, &platform_data);
1265 }
1266 
1267 #if CONFIG_DTRACE
1268 int
dtrace_proc_selfpid(void)1269 dtrace_proc_selfpid(void)
1270 {
1271 	return proc_selfpid();
1272 }
1273 
1274 int
dtrace_proc_selfppid(void)1275 dtrace_proc_selfppid(void)
1276 {
1277 	return proc_selfppid();
1278 }
1279 
1280 uid_t
dtrace_proc_selfruid(void)1281 dtrace_proc_selfruid(void)
1282 {
1283 	return current_proc()->p_ruid;
1284 }
1285 #endif /* CONFIG_DTRACE */
1286 
1287 /*!
1288  * @function proc_parent()
1289  *
1290  * @brief
1291  * Returns a ref on the parent of @c p.
1292  *
1293  * @discussion
1294  * Returns a reference on the parent, or @c PROC_NULL
1295  * if both @c p and its parent are zombies.
1296  *
1297  * If the parent is currently dying, then this function waits
1298  * for the situation to be resolved.
1299  *
1300  * This function never returns @c PROC_NULL if @c p isn't
1301  * a zombie (@c p_stat is @c SZOMB) yet.
1302  */
1303 proc_t
proc_parent(proc_t p)1304 proc_parent(proc_t p)
1305 {
1306 	proc_t parent;
1307 	proc_t pp;
1308 
1309 	proc_list_lock();
1310 
1311 	while (1) {
1312 		pp = p->p_pptr;
1313 		parent = proc_ref(pp, true);
1314 		/* Check if we got a proc ref and it is still the parent */
1315 		if (parent != PROC_NULL) {
1316 			if (parent == p->p_pptr) {
1317 				/*
1318 				 * We have a ref on the parent and it is still
1319 				 * our parent, return the ref
1320 				 */
1321 				proc_list_unlock();
1322 				return parent;
1323 			}
1324 
1325 			/*
1326 			 * Our parent changed while we slept on proc_ref,
1327 			 * drop the ref on old parent and retry.
1328 			 */
1329 			proc_rele(parent);
1330 			continue;
1331 		}
1332 
1333 		if (pp != p->p_pptr) {
1334 			/*
1335 			 * We didn't get a ref, but parent changed from what
1336 			 * we last saw before we slept in proc_ref, try again
1337 			 * with new parent.
1338 			 */
1339 			continue;
1340 		}
1341 
1342 		if ((pp->p_listflag & P_LIST_CHILDDRAINED) == 0) {
1343 			/* Parent did not change, but we also did not get a
1344 			 * ref on parent, sleep if the parent has not drained
1345 			 * its children and then retry.
1346 			 */
1347 			pp->p_listflag |= P_LIST_CHILDLKWAIT;
1348 			msleep(&pp->p_childrencnt, &proc_list_mlock, 0, "proc_parent", 0);
1349 			continue;
1350 		}
1351 
1352 		/* Parent has died and drained its children and we still
1353 		 * point to it, return NULL.
1354 		 */
1355 		proc_list_unlock();
1356 		return PROC_NULL;
1357 	}
1358 }
1359 
1360 static boolean_t
proc_parent_is_currentproc(proc_t p)1361 proc_parent_is_currentproc(proc_t p)
1362 {
1363 	boolean_t ret = FALSE;
1364 
1365 	proc_list_lock();
1366 	if (p->p_pptr == current_proc()) {
1367 		ret = TRUE;
1368 	}
1369 
1370 	proc_list_unlock();
1371 	return ret;
1372 }
1373 
1374 void
proc_name(int pid,char * buf,int size)1375 proc_name(int pid, char * buf, int size)
1376 {
1377 	proc_t p;
1378 
1379 	if (size <= 0) {
1380 		return;
1381 	}
1382 
1383 	bzero(buf, size);
1384 
1385 	if ((p = proc_find(pid)) != PROC_NULL) {
1386 		strlcpy(buf, &p->p_comm[0], MIN((int)sizeof(p->p_comm), size));
1387 		proc_rele(p);
1388 	}
1389 }
1390 
1391 void
proc_name_kdp(proc_t p,char * buf,int size)1392 proc_name_kdp(proc_t p, char * buf, int size)
1393 {
1394 	if (p == PROC_NULL) {
1395 		return;
1396 	}
1397 
1398 	if ((size_t)size > sizeof(p->p_comm)) {
1399 		strlcpy(buf, &p->p_name[0], MIN((int)sizeof(p->p_name), size));
1400 	} else {
1401 		strlcpy(buf, &p->p_comm[0], MIN((int)sizeof(p->p_comm), size));
1402 	}
1403 }
1404 
1405 boolean_t
proc_binary_uuid_kdp(task_t task,uuid_t uuid)1406 proc_binary_uuid_kdp(task_t task, uuid_t uuid)
1407 {
1408 	proc_t p = get_bsdtask_info(task);
1409 	if (p == PROC_NULL) {
1410 		return FALSE;
1411 	}
1412 
1413 	proc_getexecutableuuid(p, uuid, sizeof(uuid_t));
1414 
1415 	return TRUE;
1416 }
1417 
1418 int
proc_threadname_kdp(void * uth,char * buf,size_t size)1419 proc_threadname_kdp(void * uth, char * buf, size_t size)
1420 {
1421 	if (size < MAXTHREADNAMESIZE) {
1422 		/* this is really just a protective measure for the future in
1423 		 * case the thread name size in stackshot gets out of sync with
1424 		 * the BSD max thread name size. Note that bsd_getthreadname
1425 		 * doesn't take input buffer size into account. */
1426 		return -1;
1427 	}
1428 
1429 	if (uth != NULL) {
1430 		bsd_getthreadname(uth, buf);
1431 	}
1432 	return 0;
1433 }
1434 
1435 
1436 /* note that this function is generally going to be called from stackshot,
1437  * and the arguments will be coming from a struct which is declared packed
1438  * thus the input arguments will in general be unaligned. We have to handle
1439  * that here. */
1440 void
proc_starttime_kdp(void * p,unaligned_u64 * tv_sec,unaligned_u64 * tv_usec,unaligned_u64 * abstime)1441 proc_starttime_kdp(void *p, unaligned_u64 *tv_sec, unaligned_u64 *tv_usec, unaligned_u64 *abstime)
1442 {
1443 	proc_t pp = (proc_t)p;
1444 	if (pp != PROC_NULL) {
1445 		if (tv_sec != NULL) {
1446 			*tv_sec = pp->p_start.tv_sec;
1447 		}
1448 		if (tv_usec != NULL) {
1449 			*tv_usec = pp->p_start.tv_usec;
1450 		}
1451 		if (abstime != NULL) {
1452 			if (pp->p_stats != NULL) {
1453 				*abstime = pp->p_stats->ps_start;
1454 			} else {
1455 				*abstime = 0;
1456 			}
1457 		}
1458 	}
1459 }
1460 
1461 void
proc_archinfo_kdp(void * p,cpu_type_t * cputype,cpu_subtype_t * cpusubtype)1462 proc_archinfo_kdp(void* p, cpu_type_t* cputype, cpu_subtype_t* cpusubtype)
1463 {
1464 	proc_t pp = (proc_t)p;
1465 	if (pp != PROC_NULL) {
1466 		*cputype = pp->p_cputype;
1467 		*cpusubtype = pp->p_cpusubtype;
1468 	}
1469 }
1470 
1471 const char *
proc_name_address(void * p)1472 proc_name_address(void *p)
1473 {
1474 	return &((proc_t)p)->p_comm[0];
1475 }
1476 
1477 char *
proc_longname_address(void * p)1478 proc_longname_address(void *p)
1479 {
1480 	return &((proc_t)p)->p_name[0];
1481 }
1482 
1483 const char *
proc_best_name(proc_t p)1484 proc_best_name(proc_t p)
1485 {
1486 	if (p->p_name[0] != '\0') {
1487 		return &p->p_name[0];
1488 	}
1489 	return &p->p_comm[0];
1490 }
1491 
1492 void
proc_best_name_for_pid(int pid,char * buf,int size)1493 proc_best_name_for_pid(int pid, char * buf, int size)
1494 {
1495 	proc_t p;
1496 
1497 	if (size <= 0) {
1498 		return;
1499 	}
1500 
1501 	bzero(buf, size);
1502 
1503 	if ((p = proc_find(pid)) != PROC_NULL) {
1504 		if (p->p_name[0] != '\0') {
1505 			strlcpy(buf, &p->p_name[0], MIN((int)sizeof(p->p_name), size));
1506 		} else {
1507 			strlcpy(buf, &p->p_comm[0], MIN((int)sizeof(p->p_comm), size));
1508 		}
1509 		proc_rele(p);
1510 	}
1511 }
1512 
1513 void
proc_selfname(char * buf,int size)1514 proc_selfname(char * buf, int  size)
1515 {
1516 	proc_t p;
1517 
1518 	if (size <= 0) {
1519 		return;
1520 	}
1521 
1522 	bzero(buf, size);
1523 
1524 	if ((p = current_proc()) != (proc_t)0) {
1525 		strlcpy(buf, &p->p_name[0], MIN((int)sizeof(p->p_name), size));
1526 	}
1527 }
1528 
1529 void
proc_signal(int pid,int signum)1530 proc_signal(int pid, int signum)
1531 {
1532 	proc_t p;
1533 
1534 	if ((p = proc_find(pid)) != PROC_NULL) {
1535 		psignal(p, signum);
1536 		proc_rele(p);
1537 	}
1538 }
1539 
1540 int
proc_issignal(int pid,sigset_t mask)1541 proc_issignal(int pid, sigset_t mask)
1542 {
1543 	proc_t p;
1544 	int error = 0;
1545 
1546 	if ((p = proc_find(pid)) != PROC_NULL) {
1547 		error = proc_pendingsignals(p, mask);
1548 		proc_rele(p);
1549 	}
1550 
1551 	return error;
1552 }
1553 
1554 int
proc_noremotehang(proc_t p)1555 proc_noremotehang(proc_t p)
1556 {
1557 	int retval = 0;
1558 
1559 	if (p) {
1560 		retval = p->p_flag & P_NOREMOTEHANG;
1561 	}
1562 	return retval? 1: 0;
1563 }
1564 
1565 int
proc_exiting(proc_t p)1566 proc_exiting(proc_t p)
1567 {
1568 	int retval = 0;
1569 
1570 	if (p) {
1571 		retval = p->p_lflag & P_LEXIT;
1572 	}
1573 	return retval? 1: 0;
1574 }
1575 
1576 int
proc_in_teardown(proc_t p)1577 proc_in_teardown(proc_t p)
1578 {
1579 	int retval = 0;
1580 
1581 	if (p) {
1582 		retval = p->p_lflag & P_LPEXIT;
1583 	}
1584 	return retval? 1: 0;
1585 }
1586 
1587 int
proc_lvfork(proc_t p __unused)1588 proc_lvfork(proc_t p __unused)
1589 {
1590 	return 0;
1591 }
1592 
1593 int
proc_increment_ru_oublock(proc_t p,long * origvalp)1594 proc_increment_ru_oublock(proc_t p, long *origvalp)
1595 {
1596 	long origval;
1597 
1598 	if (p && p->p_stats) {
1599 		origval = OSIncrementAtomicLong(&p->p_stats->p_ru.ru_oublock);
1600 		if (origvalp) {
1601 			*origvalp = origval;
1602 		}
1603 		return 0;
1604 	}
1605 
1606 	return EINVAL;
1607 }
1608 
1609 int
proc_isabortedsignal(proc_t p)1610 proc_isabortedsignal(proc_t p)
1611 {
1612 	if ((p != kernproc) && current_thread_aborted() &&
1613 	    (!(p->p_acflag & AXSIG) || (p->exit_thread != current_thread()) ||
1614 	    (p->p_sigacts.ps_sig < 1) || (p->p_sigacts.ps_sig >= NSIG) ||
1615 	    !hassigprop(p->p_sigacts.ps_sig, SA_CORE))) {
1616 		return 1;
1617 	}
1618 
1619 	return 0;
1620 }
1621 
1622 int
proc_forcequota(proc_t p)1623 proc_forcequota(proc_t p)
1624 {
1625 	int retval = 0;
1626 
1627 	if (p) {
1628 		retval = p->p_flag & P_FORCEQUOTA;
1629 	}
1630 	return retval? 1: 0;
1631 }
1632 
1633 int
proc_suser(proc_t p)1634 proc_suser(proc_t p)
1635 {
1636 	int error;
1637 
1638 	smr_proc_task_enter();
1639 	error = suser(proc_ucred_smr(p), &p->p_acflag);
1640 	smr_proc_task_leave();
1641 	return error;
1642 }
1643 
1644 task_t
proc_task(proc_t proc)1645 proc_task(proc_t proc)
1646 {
1647 	task_t task_from_proc = proc_get_task_raw(proc);
1648 	return (proc->p_lflag & P_LHASTASK) ? task_from_proc : NULL;
1649 }
1650 
1651 void
proc_set_task(proc_t proc,task_t task)1652 proc_set_task(proc_t proc, task_t task)
1653 {
1654 	task_t task_from_proc = proc_get_task_raw(proc);
1655 	if (task == NULL) {
1656 		proc->p_lflag &= ~P_LHASTASK;
1657 	} else {
1658 		if (task != task_from_proc) {
1659 			panic("proc_set_task trying to set random task %p", task);
1660 		}
1661 		proc->p_lflag |= P_LHASTASK;
1662 	}
1663 }
1664 
1665 task_t
proc_get_task_raw(proc_t proc)1666 proc_get_task_raw(proc_t proc)
1667 {
1668 	return (task_t)((uintptr_t)proc + proc_struct_size);
1669 }
1670 
1671 proc_t
task_get_proc_raw(task_t task)1672 task_get_proc_raw(task_t task)
1673 {
1674 	return (proc_t)((uintptr_t)task - proc_struct_size);
1675 }
1676 
1677 /*
1678  * Obtain the first thread in a process
1679  *
1680  * XXX This is a bad thing to do; it exists predominantly to support the
1681  * XXX use of proc_t's in places that should really be using
1682  * XXX thread_t's instead.  This maintains historical behaviour, but really
1683  * XXX needs an audit of the context (proxy vs. not) to clean up.
1684  */
1685 thread_t
proc_thread(proc_t proc)1686 proc_thread(proc_t proc)
1687 {
1688 	LCK_MTX_ASSERT(&proc->p_mlock, LCK_MTX_ASSERT_OWNED);
1689 
1690 	uthread_t uth = TAILQ_FIRST(&proc->p_uthlist);
1691 
1692 	if (uth != NULL) {
1693 		return get_machthread(uth);
1694 	}
1695 
1696 	return NULL;
1697 }
1698 
1699 kauth_cred_t
proc_ucred_unsafe(proc_t p)1700 proc_ucred_unsafe(proc_t p)
1701 {
1702 	kauth_cred_t cred = smr_serialized_load(&proc_get_ro(p)->p_ucred);
1703 
1704 	return kauth_cred_require(cred);
1705 }
1706 
1707 kauth_cred_t
proc_ucred_smr(proc_t p)1708 proc_ucred_smr(proc_t p)
1709 {
1710 	assert(smr_entered(&smr_proc_task));
1711 	return proc_ucred_unsafe(p);
1712 }
1713 
1714 kauth_cred_t
proc_ucred_locked(proc_t p)1715 proc_ucred_locked(proc_t p)
1716 {
1717 	LCK_MTX_ASSERT(&p->p_ucred_mlock, LCK_ASSERT_OWNED);
1718 	return proc_ucred_unsafe(p);
1719 }
1720 
1721 struct uthread *
current_uthread(void)1722 current_uthread(void)
1723 {
1724 	return get_bsdthread_info(current_thread());
1725 }
1726 
1727 
1728 int
proc_is64bit(proc_t p)1729 proc_is64bit(proc_t p)
1730 {
1731 	return IS_64BIT_PROCESS(p);
1732 }
1733 
1734 int
proc_is64bit_data(proc_t p)1735 proc_is64bit_data(proc_t p)
1736 {
1737 	assert(proc_task(p));
1738 	return (int)task_get_64bit_data(proc_task(p));
1739 }
1740 
1741 int
proc_isinitproc(proc_t p)1742 proc_isinitproc(proc_t p)
1743 {
1744 	if (initproc == NULL) {
1745 		return 0;
1746 	}
1747 	return p == initproc;
1748 }
1749 
1750 int
proc_pidversion(proc_t p)1751 proc_pidversion(proc_t p)
1752 {
1753 	return proc_get_ro(p)->p_idversion;
1754 }
1755 
1756 void
proc_setpidversion(proc_t p,int idversion)1757 proc_setpidversion(proc_t p, int idversion)
1758 {
1759 	zalloc_ro_update_field(ZONE_ID_PROC_RO, proc_get_ro(p), p_idversion,
1760 	    &idversion);
1761 }
1762 
1763 uint32_t
proc_persona_id(proc_t p)1764 proc_persona_id(proc_t p)
1765 {
1766 	return (uint32_t)persona_id_from_proc(p);
1767 }
1768 
1769 uint32_t
proc_getuid(proc_t p)1770 proc_getuid(proc_t p)
1771 {
1772 	return p->p_uid;
1773 }
1774 
1775 uint32_t
proc_getgid(proc_t p)1776 proc_getgid(proc_t p)
1777 {
1778 	return p->p_gid;
1779 }
1780 
1781 uint64_t
proc_uniqueid(proc_t p)1782 proc_uniqueid(proc_t p)
1783 {
1784 	if (p == kernproc) {
1785 		return 0;
1786 	}
1787 
1788 	return proc_get_ro(p)->p_uniqueid;
1789 }
1790 
1791 uint64_t proc_uniqueid_task(void *p_arg, void *t);
1792 /*
1793  * During exec, two tasks point at the proc.  This function is used
1794  * to gives tasks a unique ID; we make the matching task have the
1795  * proc's uniqueid, and any other task gets the high-bit flipped.
1796  * (We need to try to avoid returning UINT64_MAX, which is the
1797  * which is the uniqueid of a task without a proc. (e.g. while exiting))
1798  *
1799  * Only used by get_task_uniqueid(); do not add additional callers.
1800  */
1801 uint64_t
proc_uniqueid_task(void * p_arg,void * t __unused)1802 proc_uniqueid_task(void *p_arg, void *t __unused)
1803 {
1804 	proc_t p = p_arg;
1805 	uint64_t uniqueid = proc_uniqueid(p);
1806 	return uniqueid ^ (__probable(!proc_is_shadow(p)) ? 0 : (1ull << 63));
1807 }
1808 
1809 uint64_t
proc_puniqueid(proc_t p)1810 proc_puniqueid(proc_t p)
1811 {
1812 	return p->p_puniqueid;
1813 }
1814 
1815 void
proc_coalitionids(__unused proc_t p,__unused uint64_t ids[COALITION_NUM_TYPES])1816 proc_coalitionids(__unused proc_t p, __unused uint64_t ids[COALITION_NUM_TYPES])
1817 {
1818 #if CONFIG_COALITIONS
1819 	task_coalition_ids(proc_task(p), ids);
1820 #else
1821 	memset(ids, 0, sizeof(uint64_t[COALITION_NUM_TYPES]));
1822 #endif
1823 	return;
1824 }
1825 
1826 uint64_t
proc_was_throttled(proc_t p)1827 proc_was_throttled(proc_t p)
1828 {
1829 	return p->was_throttled;
1830 }
1831 
1832 uint64_t
proc_did_throttle(proc_t p)1833 proc_did_throttle(proc_t p)
1834 {
1835 	return p->did_throttle;
1836 }
1837 
1838 int
proc_getcdhash(proc_t p,unsigned char * cdhash)1839 proc_getcdhash(proc_t p, unsigned char *cdhash)
1840 {
1841 	if (p == kernproc) {
1842 		return EINVAL;
1843 	}
1844 	return vn_getcdhash(p->p_textvp, p->p_textoff, cdhash, NULL);
1845 }
1846 
1847 uint64_t
proc_getcsflags(proc_t p)1848 proc_getcsflags(proc_t p)
1849 {
1850 	return proc_get_ro(p)->p_csflags;
1851 }
1852 
1853 /* This variant runs in stackshot context and must not take locks. */
1854 uint64_t
proc_getcsflags_kdp(void * p)1855 proc_getcsflags_kdp(void * p)
1856 {
1857 	proc_t proc = (proc_t)p;
1858 	if (p == PROC_NULL) {
1859 		return 0;
1860 	}
1861 	return proc_getcsflags(proc);
1862 }
1863 
1864 void
proc_csflags_update(proc_t p,uint64_t flags)1865 proc_csflags_update(proc_t p, uint64_t flags)
1866 {
1867 	uint32_t csflags = (uint32_t)flags;
1868 
1869 	if (p != kernproc) {
1870 		zalloc_ro_update_field(ZONE_ID_PROC_RO, proc_get_ro(p),
1871 		    p_csflags, &csflags);
1872 	}
1873 }
1874 
1875 void
proc_csflags_set(proc_t p,uint64_t flags)1876 proc_csflags_set(proc_t p, uint64_t flags)
1877 {
1878 	proc_csflags_update(p, proc_getcsflags(p) | (uint32_t)flags);
1879 }
1880 
1881 void
proc_csflags_clear(proc_t p,uint64_t flags)1882 proc_csflags_clear(proc_t p, uint64_t flags)
1883 {
1884 	proc_csflags_update(p, proc_getcsflags(p) & ~(uint32_t)flags);
1885 }
1886 
1887 uint8_t *
proc_syscall_filter_mask(proc_t p)1888 proc_syscall_filter_mask(proc_t p)
1889 {
1890 	return proc_get_ro(p)->syscall_filter_mask;
1891 }
1892 
1893 void
proc_syscall_filter_mask_set(proc_t p,uint8_t * mask)1894 proc_syscall_filter_mask_set(proc_t p, uint8_t *mask)
1895 {
1896 	zalloc_ro_update_field(ZONE_ID_PROC_RO, proc_get_ro(p),
1897 	    syscall_filter_mask, &mask);
1898 }
1899 
1900 int
proc_exitstatus(proc_t p)1901 proc_exitstatus(proc_t p)
1902 {
1903 	return p->p_xstat & 0xffff;
1904 }
1905 
1906 bool
proc_is_zombie(proc_t p)1907 proc_is_zombie(proc_t p)
1908 {
1909 	return proc_list_exited(p);
1910 }
1911 
1912 void
proc_setexecutableuuid(proc_t p,const unsigned char * uuid)1913 proc_setexecutableuuid(proc_t p, const unsigned char *uuid)
1914 {
1915 	memcpy(p->p_uuid, uuid, sizeof(p->p_uuid));
1916 }
1917 
1918 const unsigned char *
proc_executableuuid_addr(proc_t p)1919 proc_executableuuid_addr(proc_t p)
1920 {
1921 	return &p->p_uuid[0];
1922 }
1923 
1924 void
proc_getexecutableuuid(proc_t p,unsigned char * uuidbuf,unsigned long size)1925 proc_getexecutableuuid(proc_t p, unsigned char *uuidbuf, unsigned long size)
1926 {
1927 	if (size >= sizeof(uuid_t)) {
1928 		memcpy(uuidbuf, proc_executableuuid_addr(p), sizeof(uuid_t));
1929 	}
1930 }
1931 
1932 void
proc_getresponsibleuuid(proc_t p,unsigned char * __counted_by (size)uuidbuf,unsigned long size)1933 proc_getresponsibleuuid(proc_t p, unsigned char *__counted_by(size)uuidbuf, unsigned long size)
1934 {
1935 	if (size >= sizeof(uuid_t)) {
1936 		memcpy(uuidbuf, p->p_responsible_uuid, sizeof(uuid_t));
1937 	}
1938 }
1939 
1940 void
proc_setresponsibleuuid(proc_t p,unsigned char * __counted_by (size)uuidbuf,unsigned long size)1941 proc_setresponsibleuuid(proc_t p, unsigned char *__counted_by(size)uuidbuf, unsigned long size)
1942 {
1943 	if (p != NULL && uuidbuf != NULL && size >= sizeof(uuid_t)) {
1944 		memcpy(p->p_responsible_uuid, uuidbuf, sizeof(uuid_t));
1945 	}
1946 	return;
1947 }
1948 
1949 /* Return vnode for executable with an iocount. Must be released with vnode_put() */
1950 vnode_t
proc_getexecutablevnode(proc_t p)1951 proc_getexecutablevnode(proc_t p)
1952 {
1953 	vnode_t tvp  = p->p_textvp;
1954 
1955 	if (tvp != NULLVP) {
1956 		if (vnode_getwithref(tvp) == 0) {
1957 			return tvp;
1958 		}
1959 	}
1960 
1961 	return NULLVP;
1962 }
1963 
1964 /*
1965  * Similar to proc_getexecutablevnode() but returns NULLVP if the vnode is
1966  * being reclaimed rather than blocks until reclaim is done.
1967  */
1968 vnode_t
proc_getexecutablevnode_noblock(proc_t p)1969 proc_getexecutablevnode_noblock(proc_t p)
1970 {
1971 	vnode_t tvp  = p->p_textvp;
1972 
1973 	if (tvp != NULLVP) {
1974 		if (vnode_getwithref_noblock(tvp) == 0) {
1975 			return tvp;
1976 		}
1977 	}
1978 
1979 	return NULLVP;
1980 }
1981 
1982 int
proc_gettty(proc_t p,vnode_t * vp)1983 proc_gettty(proc_t p, vnode_t *vp)
1984 {
1985 	struct session *procsp;
1986 	struct pgrp *pg;
1987 	int err = EINVAL;
1988 
1989 	if (!p || !vp) {
1990 		return EINVAL;
1991 	}
1992 
1993 	if ((pg = proc_pgrp(p, &procsp)) != PGRP_NULL) {
1994 		session_lock(procsp);
1995 		vnode_t ttyvp = procsp->s_ttyvp;
1996 		int ttyvid = procsp->s_ttyvid;
1997 		if (ttyvp) {
1998 			vnode_hold(ttyvp);
1999 		}
2000 		session_unlock(procsp);
2001 
2002 		if (ttyvp) {
2003 			if (vnode_getwithvid(ttyvp, ttyvid) == 0) {
2004 				*vp = ttyvp;
2005 				err = 0;
2006 			}
2007 			vnode_drop(ttyvp);
2008 		} else {
2009 			err = ENOENT;
2010 		}
2011 
2012 		pgrp_rele(pg);
2013 	}
2014 
2015 	return err;
2016 }
2017 
2018 int
proc_gettty_dev(proc_t p,dev_t * devp)2019 proc_gettty_dev(proc_t p, dev_t *devp)
2020 {
2021 	struct pgrp *pg;
2022 	dev_t dev = NODEV;
2023 
2024 	if ((pg = proc_pgrp(p, NULL)) != PGRP_NULL) {
2025 		dev = os_atomic_load(&pg->pg_session->s_ttydev, relaxed);
2026 		pgrp_rele(pg);
2027 	}
2028 
2029 	if (dev == NODEV) {
2030 		return EINVAL;
2031 	}
2032 
2033 	*devp = dev;
2034 	return 0;
2035 }
2036 
2037 int
proc_selfexecutableargs(uint8_t * buf,size_t * buflen)2038 proc_selfexecutableargs(uint8_t *buf, size_t *buflen)
2039 {
2040 	proc_t p = current_proc();
2041 
2042 	// buflen must always be provided
2043 	if (buflen == NULL) {
2044 		return EINVAL;
2045 	}
2046 
2047 	// If a buf is provided, there must be at least enough room to fit argc
2048 	if (buf && *buflen < sizeof(p->p_argc)) {
2049 		return EINVAL;
2050 	}
2051 
2052 	if (!p->user_stack) {
2053 		return EINVAL;
2054 	}
2055 
2056 	if (buf == NULL) {
2057 		*buflen = p->p_argslen + sizeof(p->p_argc);
2058 		return 0;
2059 	}
2060 
2061 	// Copy in argc to the first 4 bytes
2062 	memcpy(buf, &p->p_argc, sizeof(p->p_argc));
2063 
2064 	if (*buflen > sizeof(p->p_argc) && p->p_argslen > 0) {
2065 		// See memory layout comment in kern_exec.c:exec_copyout_strings()
2066 		// We want to copy starting from `p_argslen` bytes away from top of stack
2067 		return copyin(p->user_stack - p->p_argslen,
2068 		           buf + sizeof(p->p_argc),
2069 		           MIN(p->p_argslen, *buflen - sizeof(p->p_argc)));
2070 	} else {
2071 		return 0;
2072 	}
2073 }
2074 
2075 off_t
proc_getexecutableoffset(proc_t p)2076 proc_getexecutableoffset(proc_t p)
2077 {
2078 	return p->p_textoff;
2079 }
2080 
2081 void
bsd_set_dependency_capable(task_t task)2082 bsd_set_dependency_capable(task_t task)
2083 {
2084 	proc_t p = get_bsdtask_info(task);
2085 
2086 	if (p) {
2087 		OSBitOrAtomic(P_DEPENDENCY_CAPABLE, &p->p_flag);
2088 	}
2089 }
2090 
2091 
2092 #ifndef __arm__
2093 int
IS_64BIT_PROCESS(proc_t p)2094 IS_64BIT_PROCESS(proc_t p)
2095 {
2096 	if (p && (p->p_flag & P_LP64)) {
2097 		return 1;
2098 	} else {
2099 		return 0;
2100 	}
2101 }
2102 #endif
2103 
2104 SMRH_TRAITS_DEFINE_SCALAR(pid_hash_traits, struct proc, p_pid, p_hash,
2105     .domain = &smr_proc_task);
2106 
2107 /*
2108  * Locate a process by number
2109  */
2110 proc_t
phash_find_locked(pid_t pid)2111 phash_find_locked(pid_t pid)
2112 {
2113 	smrh_key_t key = SMRH_SCALAR_KEY(pid);
2114 
2115 	LCK_MTX_ASSERT(&proc_list_mlock, LCK_MTX_ASSERT_OWNED);
2116 
2117 	if (!pid) {
2118 		return kernproc;
2119 	}
2120 
2121 	return smr_hash_serialized_find(&pid_hash, key, &pid_hash_traits);
2122 }
2123 
2124 void
phash_replace_locked(struct proc * old_proc,struct proc * new_proc)2125 phash_replace_locked(struct proc *old_proc, struct proc *new_proc)
2126 {
2127 	LCK_MTX_ASSERT(&proc_list_mlock, LCK_MTX_ASSERT_OWNED);
2128 
2129 	smr_hash_serialized_replace(&pid_hash,
2130 	    &old_proc->p_hash, &new_proc->p_hash, &pid_hash_traits);
2131 }
2132 
2133 void
phash_insert_locked(struct proc * p)2134 phash_insert_locked(struct proc *p)
2135 {
2136 	LCK_MTX_ASSERT(&proc_list_mlock, LCK_MTX_ASSERT_OWNED);
2137 
2138 	smr_hash_serialized_insert(&pid_hash, &p->p_hash, &pid_hash_traits);
2139 }
2140 
2141 void
phash_remove_locked(struct proc * p)2142 phash_remove_locked(struct proc *p)
2143 {
2144 	LCK_MTX_ASSERT(&proc_list_mlock, LCK_MTX_ASSERT_OWNED);
2145 
2146 	smr_hash_serialized_remove(&pid_hash, &p->p_hash, &pid_hash_traits);
2147 }
2148 
2149 proc_t
proc_find_noref_smr(int pid)2150 proc_find_noref_smr(int pid)
2151 {
2152 	smrh_key_t key = SMRH_SCALAR_KEY(pid);
2153 
2154 	if (__improbable(pid == 0)) {
2155 		return kernproc;
2156 	}
2157 
2158 	return smr_hash_entered_find(&pid_hash, key, &pid_hash_traits);
2159 }
2160 
2161 proc_t
proc_find(int pid)2162 proc_find(int pid)
2163 {
2164 	smrh_key_t key = SMRH_SCALAR_KEY(pid);
2165 	proc_t p;
2166 	uint32_t bits;
2167 	bool shadow_proc = false;
2168 
2169 	LCK_MTX_ASSERT(&proc_list_mlock, LCK_MTX_ASSERT_NOTOWNED);
2170 
2171 	if (!pid) {
2172 		return proc_ref(kernproc, false);
2173 	}
2174 
2175 retry:
2176 	p = PROC_NULL;
2177 	bits = 0;
2178 	shadow_proc = false;
2179 
2180 	smr_proc_task_enter();
2181 	p = smr_hash_entered_find(&pid_hash, key, &pid_hash_traits);
2182 	if (p) {
2183 		bits = proc_ref_try_fast(p);
2184 		shadow_proc = !!proc_is_shadow(p);
2185 	}
2186 	smr_proc_task_leave();
2187 
2188 	/* Retry if the proc is a shadow proc */
2189 	if (shadow_proc) {
2190 		if (bits) {
2191 			proc_rele(p);
2192 		}
2193 		goto retry;
2194 	}
2195 
2196 	if (__improbable(!bits)) {
2197 		return PROC_NULL;
2198 	}
2199 
2200 	if (__improbable(proc_ref_needs_wait_for_exec(bits))) {
2201 		p = proc_ref_wait_for_exec(p, bits, false);
2202 		/*
2203 		 * Retry if exec was successful since the old proc
2204 		 * would have become a shadow proc and might be in
2205 		 * middle of exiting.
2206 		 */
2207 		if (p == PROC_NULL || proc_is_shadow(p)) {
2208 			if (p != PROC_NULL) {
2209 				proc_rele(p);
2210 			}
2211 			goto retry;
2212 		}
2213 	}
2214 
2215 	return p;
2216 }
2217 
2218 proc_t
proc_find_locked(int pid)2219 proc_find_locked(int pid)
2220 {
2221 	proc_t p = PROC_NULL;
2222 
2223 retry:
2224 	p = phash_find_locked(pid);
2225 	if (p != PROC_NULL) {
2226 		uint32_t bits;
2227 
2228 		assert(!proc_is_shadow(p));
2229 
2230 		bits = proc_ref_try_fast(p);
2231 		if (__improbable(!bits)) {
2232 			return PROC_NULL;
2233 		}
2234 
2235 		if (__improbable(proc_ref_needs_wait_for_exec(bits))) {
2236 			p = proc_ref_wait_for_exec(p, bits, true);
2237 			/*
2238 			 * Retry if exec was successful since the old proc
2239 			 * would have become a shadow proc and might be in
2240 			 * middle of exiting.
2241 			 */
2242 			if (p == PROC_NULL || proc_is_shadow(p)) {
2243 				if (p != PROC_NULL) {
2244 					proc_rele(p);
2245 				}
2246 				goto retry;
2247 			}
2248 		}
2249 	}
2250 
2251 	return p;
2252 }
2253 
2254 proc_t
proc_findthread(thread_t thread)2255 proc_findthread(thread_t thread)
2256 {
2257 	proc_t p = PROC_NULL;
2258 
2259 	proc_list_lock();
2260 	{
2261 		p = (proc_t)(get_bsdthreadtask_info(thread));
2262 	}
2263 	p = proc_ref(p, true);
2264 	proc_list_unlock();
2265 	return p;
2266 }
2267 
2268 
2269 /*
2270  * Locate a zombie by PID
2271  */
2272 __private_extern__ proc_t
pzfind(pid_t pid)2273 pzfind(pid_t pid)
2274 {
2275 	proc_t p;
2276 
2277 
2278 	proc_list_lock();
2279 
2280 	LIST_FOREACH(p, &zombproc, p_list) {
2281 		if (proc_getpid(p) == pid && !proc_is_shadow(p)) {
2282 			break;
2283 		}
2284 	}
2285 
2286 	proc_list_unlock();
2287 
2288 	return p;
2289 }
2290 
2291 /*
2292  * Acquire a pgrp ref, if and only if the pgrp is non empty.
2293  */
2294 static inline bool
pg_ref_try(struct pgrp * pgrp)2295 pg_ref_try(struct pgrp *pgrp)
2296 {
2297 	return os_ref_retain_try_mask(&pgrp->pg_refcount, PGRP_REF_BITS,
2298 	           PGRP_REF_EMPTY, &p_refgrp);
2299 }
2300 
2301 static bool
pgrp_hash_obj_try_get(void * pgrp)2302 pgrp_hash_obj_try_get(void *pgrp)
2303 {
2304 	return pg_ref_try(pgrp);
2305 }
2306 /*
2307  * Unconditionally acquire a pgrp ref,
2308  * regardless of whether the pgrp is empty or not.
2309  */
2310 static inline struct pgrp *
pg_ref(struct pgrp * pgrp)2311 pg_ref(struct pgrp *pgrp)
2312 {
2313 	os_ref_retain_mask(&pgrp->pg_refcount, PGRP_REF_BITS, &p_refgrp);
2314 	return pgrp;
2315 }
2316 
2317 SMRH_TRAITS_DEFINE_SCALAR(pgrp_hash_traits, struct pgrp, pg_id, pg_hash,
2318     .domain      = &smr_proc_task,
2319     .obj_try_get = pgrp_hash_obj_try_get);
2320 
2321 /*
2322  * Locate a process group by number
2323  */
2324 bool
pghash_exists_locked(pid_t pgid)2325 pghash_exists_locked(pid_t pgid)
2326 {
2327 	smrh_key_t key = SMRH_SCALAR_KEY(pgid);
2328 
2329 	LCK_MTX_ASSERT(&proc_list_mlock, LCK_MTX_ASSERT_OWNED);
2330 
2331 	return smr_hash_serialized_find(&pgrp_hash, key, &pgrp_hash_traits);
2332 }
2333 
2334 void
pghash_insert_locked(struct pgrp * pgrp)2335 pghash_insert_locked(struct pgrp *pgrp)
2336 {
2337 	LCK_MTX_ASSERT(&proc_list_mlock, LCK_MTX_ASSERT_OWNED);
2338 
2339 	smr_hash_serialized_insert(&pgrp_hash, &pgrp->pg_hash,
2340 	    &pgrp_hash_traits);
2341 }
2342 
2343 static void
pghash_remove_locked(struct pgrp * pgrp)2344 pghash_remove_locked(struct pgrp *pgrp)
2345 {
2346 	LCK_MTX_ASSERT(&proc_list_mlock, LCK_MTX_ASSERT_OWNED);
2347 
2348 	smr_hash_serialized_remove(&pgrp_hash, &pgrp->pg_hash,
2349 	    &pgrp_hash_traits);
2350 }
2351 
2352 struct pgrp *
pgrp_find(pid_t pgid)2353 pgrp_find(pid_t pgid)
2354 {
2355 	smrh_key_t key = SMRH_SCALAR_KEY(pgid);
2356 
2357 	LCK_MTX_ASSERT(&proc_list_mlock, LCK_MTX_ASSERT_NOTOWNED);
2358 
2359 	return smr_hash_get(&pgrp_hash, key, &pgrp_hash_traits);
2360 }
2361 
2362 /* consumes one ref from pgrp */
2363 static void
pgrp_add_member(struct pgrp * pgrp,struct proc * parent,struct proc * p)2364 pgrp_add_member(struct pgrp *pgrp, struct proc *parent, struct proc *p)
2365 {
2366 	LCK_MTX_ASSERT(&proc_list_mlock, LCK_MTX_ASSERT_OWNED);
2367 
2368 	pgrp_lock(pgrp);
2369 	if (LIST_EMPTY(&pgrp->pg_members)) {
2370 		os_atomic_andnot(&pgrp->pg_refcount, PGRP_REF_EMPTY, relaxed);
2371 	}
2372 	if (parent != PROC_NULL) {
2373 		assert(pgrp == smr_serialized_load(&parent->p_pgrp));
2374 	}
2375 
2376 	LIST_INSERT_HEAD(&pgrp->pg_members, p, p_pglist);
2377 	pgrp_unlock(pgrp);
2378 
2379 	p->p_pgrpid = pgrp->pg_id;
2380 	p->p_sessionid = pgrp->pg_session->s_sid;
2381 	smr_serialized_store(&p->p_pgrp, pgrp);
2382 }
2383 
2384 /* returns one ref from pgrp */
2385 static void
pgrp_del_member(struct pgrp * pgrp,struct proc * p)2386 pgrp_del_member(struct pgrp *pgrp, struct proc *p)
2387 {
2388 	LCK_MTX_ASSERT(&proc_list_mlock, LCK_MTX_ASSERT_OWNED);
2389 
2390 	pgrp_lock(pgrp);
2391 	LIST_REMOVE(p, p_pglist);
2392 	if (LIST_EMPTY(&pgrp->pg_members)) {
2393 		os_atomic_or(&pgrp->pg_refcount, PGRP_REF_EMPTY, relaxed);
2394 	}
2395 	pgrp_unlock(pgrp);
2396 }
2397 
2398 void
pgrp_rele(struct pgrp * pgrp)2399 pgrp_rele(struct pgrp * pgrp)
2400 {
2401 	if (pgrp == PGRP_NULL) {
2402 		return;
2403 	}
2404 
2405 	if (os_ref_release_mask(&pgrp->pg_refcount, PGRP_REF_BITS, &p_refgrp) == 0) {
2406 		pgrp_destroy(pgrp);
2407 	}
2408 }
2409 
2410 struct session *
session_alloc(proc_t leader)2411 session_alloc(proc_t leader)
2412 {
2413 	struct session *sess;
2414 
2415 	sess = zalloc_flags(session_zone, Z_WAITOK | Z_ZERO | Z_NOFAIL);
2416 	lck_mtx_init(&sess->s_mlock, &proc_mlock_grp, &proc_lck_attr);
2417 	sess->s_leader = leader;
2418 	sess->s_sid = proc_getpid(leader);
2419 	sess->s_ttypgrpid = NO_PID;
2420 	os_atomic_init(&sess->s_ttydev, NODEV);
2421 	os_ref_init_mask(&sess->s_refcount, SESSION_REF_BITS,
2422 	    &p_refgrp, S_DEFAULT);
2423 
2424 	return sess;
2425 }
2426 
2427 struct tty *
session_set_tty_locked(struct session * sessp,struct tty * tp)2428 session_set_tty_locked(struct session *sessp, struct tty *tp)
2429 {
2430 	struct tty *old;
2431 
2432 	LCK_MTX_ASSERT(&sessp->s_mlock, LCK_MTX_ASSERT_OWNED);
2433 
2434 	old = sessp->s_ttyp;
2435 	ttyhold(tp);
2436 	sessp->s_ttyp = tp;
2437 	os_atomic_store(&sessp->s_ttydev, tp->t_dev, relaxed);
2438 
2439 	return old;
2440 }
2441 
2442 struct tty *
session_clear_tty_locked(struct session * sessp)2443 session_clear_tty_locked(struct session *sessp)
2444 {
2445 	struct tty *tp = sessp->s_ttyp;
2446 
2447 	LCK_MTX_ASSERT(&sessp->s_mlock, LCK_MTX_ASSERT_OWNED);
2448 	sessp->s_ttyvp = NULLVP;
2449 	sessp->s_ttyvid = 0;
2450 	sessp->s_ttyp = TTY_NULL;
2451 	sessp->s_ttypgrpid = NO_PID;
2452 	os_atomic_store(&sessp->s_ttydev, NODEV, relaxed);
2453 
2454 	return tp;
2455 }
2456 
2457 __attribute__((noinline))
2458 static void
session_destroy(struct session * sess)2459 session_destroy(struct session *sess)
2460 {
2461 	proc_list_lock();
2462 	LIST_REMOVE(sess, s_hash);
2463 	proc_list_unlock();
2464 
2465 	/*
2466 	 * Either the TTY was closed,
2467 	 * or proc_exit() destroyed it when the leader went away
2468 	 */
2469 	assert(sess->s_ttyp == TTY_NULL);
2470 
2471 	lck_mtx_destroy(&sess->s_mlock, &proc_mlock_grp);
2472 	zfree(session_zone, sess);
2473 }
2474 
2475 struct session *
session_ref(struct session * sess)2476 session_ref(struct session *sess)
2477 {
2478 	os_ref_retain_mask(&sess->s_refcount, SESSION_REF_BITS, &p_refgrp);
2479 	return sess;
2480 }
2481 
2482 void
session_rele(struct session * sess)2483 session_rele(struct session *sess)
2484 {
2485 	if (os_ref_release_mask(&sess->s_refcount, SESSION_REF_BITS, &p_refgrp) == 0) {
2486 		session_destroy(sess);
2487 	}
2488 }
2489 
2490 
2491 /*
2492  * Make a new process ready to become a useful member of society by making it
2493  * visible in all the right places and initialize its own lists to empty.
2494  *
2495  * Parameters:	parent			The parent of the process to insert
2496  *		child			The child process to insert
2497  *		in_exec			The child process is in exec
2498  *
2499  * Returns:	(void)
2500  *
2501  * Notes:	Insert a child process into the parents children list, assign
2502  *		the child the parent process pointer and PPID of the parent...
2503  */
2504 void
pinsertchild(proc_t parent,proc_t child,bool in_exec)2505 pinsertchild(proc_t parent, proc_t child, bool in_exec)
2506 {
2507 	LIST_INIT(&child->p_children);
2508 	proc_t sibling = parent;
2509 
2510 	/* For exec case, new proc is not a child of old proc, but its replacement */
2511 	if (in_exec) {
2512 		parent = proc_parent(parent);
2513 		assert(parent != PROC_NULL);
2514 
2515 		/* Copy the ptrace flags from sibling */
2516 		proc_lock(sibling);
2517 		child->p_oppid = sibling->p_oppid;
2518 		child->p_lflag |= (sibling->p_lflag & (P_LTRACED | P_LSIGEXC | P_LNOATTACH));
2519 		proc_unlock(sibling);
2520 	}
2521 
2522 	proc_list_lock();
2523 
2524 	child->p_pptr = parent;
2525 	child->p_ppid = proc_getpid(parent);
2526 	child->p_puniqueid = proc_uniqueid(parent);
2527 	child->p_xhighbits = 0;
2528 #if CONFIG_MEMORYSTATUS
2529 	memorystatus_add(child, TRUE);
2530 #endif
2531 
2532 	/* If the parent is initproc and p_orig_ppid is not 1, then set reparent flag */
2533 	if (in_exec && parent == initproc && proc_original_ppid(child) != 1) {
2534 		child->p_listflag |= P_LIST_DEADPARENT;
2535 	}
2536 
2537 	parent->p_childrencnt++;
2538 	LIST_INSERT_HEAD(&parent->p_children, child, p_sibling);
2539 
2540 	LIST_INSERT_HEAD(&allproc, child, p_list);
2541 	/* mark the completion of proc creation */
2542 	os_atomic_andnot(&child->p_refcount, P_REF_NEW, relaxed);
2543 
2544 	proc_list_unlock();
2545 	if (in_exec) {
2546 		proc_rele(parent);
2547 	}
2548 }
2549 
2550 /*
2551  * Reparent all children of old proc to new proc.
2552  *
2553  * Parameters:	old process		Old process.
2554  *		new process		New process.
2555  *
2556  * Returns:	None.
2557  */
2558 void
p_reparentallchildren(proc_t old_proc,proc_t new_proc)2559 p_reparentallchildren(proc_t old_proc, proc_t new_proc)
2560 {
2561 	proc_t child;
2562 
2563 	LIST_INIT(&new_proc->p_children);
2564 
2565 	/* Wait for parent ref to drop */
2566 	proc_childdrainstart(old_proc);
2567 
2568 	/* Reparent child from old proc to new proc */
2569 	while ((child = old_proc->p_children.lh_first) != NULL) {
2570 		LIST_REMOVE(child, p_sibling);
2571 		old_proc->p_childrencnt--;
2572 		child->p_pptr = new_proc;
2573 		LIST_INSERT_HEAD(&new_proc->p_children, child, p_sibling);
2574 		new_proc->p_childrencnt++;
2575 	}
2576 
2577 	new_proc->si_pid = old_proc->si_pid;
2578 	new_proc->si_status = old_proc->si_status;
2579 	new_proc->si_code = old_proc->si_code;
2580 	new_proc->si_uid = old_proc->si_uid;
2581 
2582 	proc_childdrainend(old_proc);
2583 }
2584 
2585 /*
2586  * Move p to a new or existing process group (and session)
2587  *
2588  * Returns:	0			Success
2589  *		ESRCH			No such process
2590  */
2591 int
enterpgrp(proc_t p,pid_t pgid,int mksess)2592 enterpgrp(proc_t p, pid_t pgid, int mksess)
2593 {
2594 	struct pgrp *pgrp;
2595 	struct pgrp *mypgrp;
2596 	struct session *procsp;
2597 
2598 	pgrp = pgrp_find(pgid);
2599 	mypgrp = proc_pgrp(p, &procsp);
2600 
2601 #if DIAGNOSTIC
2602 	if (pgrp != NULL && mksess) {   /* firewalls */
2603 		panic("enterpgrp: setsid into non-empty pgrp");
2604 	}
2605 	if (SESS_LEADER(p, mypgrp->pg_session)) {
2606 		panic("enterpgrp: session leader attempted setpgrp");
2607 	}
2608 #endif
2609 	if (pgrp == PGRP_NULL) {
2610 		struct session *sess;
2611 		pid_t savepid = proc_getpid(p);
2612 		proc_t np = PROC_NULL;
2613 
2614 		/*
2615 		 * new process group
2616 		 */
2617 #if DIAGNOSTIC
2618 		if (proc_getpid(p) != pgid) {
2619 			panic("enterpgrp: new pgrp and pid != pgid");
2620 		}
2621 #endif
2622 		if ((np = proc_find(savepid)) == NULL || np != p) {
2623 			if (np != PROC_NULL) {
2624 				proc_rele(np);
2625 			}
2626 			pgrp_rele(mypgrp);
2627 			return ESRCH;
2628 		}
2629 		proc_rele(np);
2630 
2631 		pgrp = pgrp_alloc(pgid, PGRP_REF_EMPTY);
2632 
2633 		if (mksess) {
2634 			/*
2635 			 * new session
2636 			 */
2637 			sess = session_alloc(p);
2638 
2639 			bcopy(mypgrp->pg_session->s_login, sess->s_login,
2640 			    sizeof(sess->s_login));
2641 			os_atomic_andnot(&p->p_flag, P_CONTROLT, relaxed);
2642 		} else {
2643 			sess = session_ref(procsp);
2644 		}
2645 
2646 		proc_list_lock();
2647 		pgrp->pg_session = sess;
2648 		p->p_sessionid = sess->s_sid;
2649 		pghash_insert_locked(pgrp);
2650 		if (mksess) {
2651 			LIST_INSERT_HEAD(SESSHASH(sess->s_sid), sess, s_hash);
2652 		}
2653 		proc_list_unlock();
2654 	} else if (pgrp == mypgrp) {
2655 		pgrp_rele(pgrp);
2656 		pgrp_rele(mypgrp);
2657 		return 0;
2658 	}
2659 
2660 	/*
2661 	 * Adjust eligibility of affected pgrps to participate in job control.
2662 	 * Increment eligibility counts before decrementing, otherwise we
2663 	 * could reach 0 spuriously during the first call.
2664 	 */
2665 	fixjobc(p, pgrp, 1);
2666 	fixjobc(p, mypgrp, 0);
2667 
2668 	pgrp_rele(mypgrp);
2669 	pgrp_replace(p, pgrp);
2670 
2671 	return 0;
2672 }
2673 
2674 /*
2675  * remove process from process group
2676  */
2677 struct pgrp *
pgrp_leave_locked(proc_t p)2678 pgrp_leave_locked(proc_t p)
2679 {
2680 	struct pgrp *pg;
2681 
2682 	LCK_MTX_ASSERT(&proc_list_mlock, LCK_MTX_ASSERT_OWNED);
2683 
2684 	pg = smr_serialized_load(&p->p_pgrp);
2685 	pgrp_del_member(pg, p);
2686 	p->p_pgrpid = PGRPID_DEAD;
2687 	smr_clear_store(&p->p_pgrp);
2688 
2689 	return pg;
2690 }
2691 
2692 struct pgrp *
pgrp_enter_locked(struct proc * parent,struct proc * child)2693 pgrp_enter_locked(struct proc *parent, struct proc *child)
2694 {
2695 	struct pgrp *pgrp;
2696 
2697 	LCK_MTX_ASSERT(&proc_list_mlock, LCK_MTX_ASSERT_OWNED);
2698 
2699 	pgrp = pg_ref(smr_serialized_load(&parent->p_pgrp));
2700 	pgrp_add_member(pgrp, parent, child);
2701 	return pgrp;
2702 }
2703 
2704 /*
2705  * delete a process group
2706  */
2707 static void
pgrp_free(smr_node_t node)2708 pgrp_free(smr_node_t node)
2709 {
2710 	struct pgrp *pgrp = __container_of(node, struct pgrp, pg_smr_node);
2711 
2712 	zfree(pgrp_zone, pgrp);
2713 }
2714 
2715 __attribute__((noinline))
2716 static void
pgrp_destroy(struct pgrp * pgrp)2717 pgrp_destroy(struct pgrp *pgrp)
2718 {
2719 	struct session *sess;
2720 
2721 	assert(LIST_EMPTY(&pgrp->pg_members));
2722 	assert(os_ref_get_raw_mask(&pgrp->pg_refcount) & PGRP_REF_EMPTY);
2723 
2724 	proc_list_lock();
2725 	pghash_remove_locked(pgrp);
2726 	proc_list_unlock();
2727 
2728 	sess = pgrp->pg_session;
2729 	pgrp->pg_session = SESSION_NULL;
2730 	session_rele(sess);
2731 
2732 	lck_mtx_destroy(&pgrp->pg_mlock, &proc_mlock_grp);
2733 	if (os_ref_release_raw(&pgrp->pg_hashref, &p_refgrp) == 0) {
2734 		smr_proc_task_call(&pgrp->pg_smr_node, sizeof(*pgrp), pgrp_free);
2735 	}
2736 }
2737 
2738 
2739 /*
2740  * Adjust pgrp jobc counters when specified process changes process group.
2741  * We count the number of processes in each process group that "qualify"
2742  * the group for terminal job control (those with a parent in a different
2743  * process group of the same session).  If that count reaches zero, the
2744  * process group becomes orphaned.  Check both the specified process'
2745  * process group and that of its children.
2746  * entering == 0 => p is leaving specified group.
2747  * entering == 1 => p is entering specified group.
2748  */
2749 int
fixjob_callback(proc_t p,void * arg)2750 fixjob_callback(proc_t p, void * arg)
2751 {
2752 	struct fixjob_iterargs *fp;
2753 	struct pgrp * pg, *hispg;
2754 	struct session * mysession, *hissess;
2755 	int entering;
2756 
2757 	fp = (struct fixjob_iterargs *)arg;
2758 	pg = fp->pg;
2759 	mysession = fp->mysession;
2760 	entering = fp->entering;
2761 
2762 	hispg = proc_pgrp(p, &hissess);
2763 
2764 	if (hispg != pg && hissess == mysession) {
2765 		pgrp_lock(hispg);
2766 		if (entering) {
2767 			hispg->pg_jobc++;
2768 			pgrp_unlock(hispg);
2769 		} else if (--hispg->pg_jobc == 0) {
2770 			pgrp_unlock(hispg);
2771 			orphanpg(hispg);
2772 		} else {
2773 			pgrp_unlock(hispg);
2774 		}
2775 	}
2776 	pgrp_rele(hispg);
2777 
2778 	return PROC_RETURNED;
2779 }
2780 
2781 void
fixjobc(proc_t p,struct pgrp * pgrp,int entering)2782 fixjobc(proc_t p, struct pgrp *pgrp, int entering)
2783 {
2784 	struct pgrp *hispgrp = PGRP_NULL;
2785 	struct session *hissess = SESSION_NULL;
2786 	struct session *mysession = pgrp->pg_session;
2787 	proc_t parent;
2788 	struct fixjob_iterargs fjarg;
2789 	boolean_t proc_parent_self;
2790 
2791 	/*
2792 	 * Check if p's parent is current proc, if yes then no need to take
2793 	 * a ref; calling proc_parent with current proc as parent may
2794 	 * deadlock if current proc is exiting.
2795 	 */
2796 	proc_parent_self = proc_parent_is_currentproc(p);
2797 	if (proc_parent_self) {
2798 		parent = current_proc();
2799 	} else {
2800 		parent = proc_parent(p);
2801 	}
2802 
2803 	if (parent != PROC_NULL) {
2804 		hispgrp = proc_pgrp(parent, &hissess);
2805 		if (!proc_parent_self) {
2806 			proc_rele(parent);
2807 		}
2808 	}
2809 
2810 	/*
2811 	 * Check p's parent to see whether p qualifies its own process
2812 	 * group; if so, adjust count for p's process group.
2813 	 */
2814 	if (hispgrp != pgrp && hissess == mysession) {
2815 		pgrp_lock(pgrp);
2816 		if (entering) {
2817 			pgrp->pg_jobc++;
2818 			pgrp_unlock(pgrp);
2819 		} else if (--pgrp->pg_jobc == 0) {
2820 			pgrp_unlock(pgrp);
2821 			orphanpg(pgrp);
2822 		} else {
2823 			pgrp_unlock(pgrp);
2824 		}
2825 	}
2826 
2827 	pgrp_rele(hispgrp);
2828 
2829 	/*
2830 	 * Check this process' children to see whether they qualify
2831 	 * their process groups; if so, adjust counts for children's
2832 	 * process groups.
2833 	 */
2834 	fjarg.pg = pgrp;
2835 	fjarg.mysession = mysession;
2836 	fjarg.entering = entering;
2837 	proc_childrenwalk(p, fixjob_callback, &fjarg);
2838 }
2839 
2840 /*
2841  * The pidlist_* routines support the functions in this file that
2842  * walk lists of processes applying filters and callouts to the
2843  * elements of the list.
2844  *
2845  * A prior implementation used a single linear array, which can be
2846  * tricky to allocate on large systems. This implementation creates
2847  * an SLIST of modestly sized arrays of PIDS_PER_ENTRY elements.
2848  *
2849  * The array should be sized large enough to keep the overhead of
2850  * walking the list low, but small enough that blocking allocations of
2851  * pidlist_entry_t structures always succeed.
2852  */
2853 
2854 #define PIDS_PER_ENTRY 1021
2855 
2856 typedef struct pidlist_entry {
2857 	SLIST_ENTRY(pidlist_entry) pe_link;
2858 	u_int pe_nused;
2859 	pid_t pe_pid[PIDS_PER_ENTRY];
2860 } pidlist_entry_t;
2861 
2862 typedef struct {
2863 	SLIST_HEAD(, pidlist_entry) pl_head;
2864 	struct pidlist_entry *pl_active;
2865 	u_int pl_nalloc;
2866 } pidlist_t;
2867 
2868 static __inline__ pidlist_t *
pidlist_init(pidlist_t * pl)2869 pidlist_init(pidlist_t *pl)
2870 {
2871 	SLIST_INIT(&pl->pl_head);
2872 	pl->pl_active = NULL;
2873 	pl->pl_nalloc = 0;
2874 	return pl;
2875 }
2876 
2877 static u_int
pidlist_alloc(pidlist_t * pl,u_int needed)2878 pidlist_alloc(pidlist_t *pl, u_int needed)
2879 {
2880 	while (pl->pl_nalloc < needed) {
2881 		pidlist_entry_t *pe = kalloc_type(pidlist_entry_t,
2882 		    Z_WAITOK | Z_ZERO | Z_NOFAIL);
2883 		SLIST_INSERT_HEAD(&pl->pl_head, pe, pe_link);
2884 		pl->pl_nalloc += (sizeof(pe->pe_pid) / sizeof(pe->pe_pid[0]));
2885 	}
2886 	return pl->pl_nalloc;
2887 }
2888 
2889 static void
pidlist_free(pidlist_t * pl)2890 pidlist_free(pidlist_t *pl)
2891 {
2892 	pidlist_entry_t *pe;
2893 	while (NULL != (pe = SLIST_FIRST(&pl->pl_head))) {
2894 		SLIST_FIRST(&pl->pl_head) = SLIST_NEXT(pe, pe_link);
2895 		kfree_type(pidlist_entry_t, pe);
2896 	}
2897 	pl->pl_nalloc = 0;
2898 }
2899 
2900 static __inline__ void
pidlist_set_active(pidlist_t * pl)2901 pidlist_set_active(pidlist_t *pl)
2902 {
2903 	pl->pl_active = SLIST_FIRST(&pl->pl_head);
2904 	assert(pl->pl_active);
2905 }
2906 
2907 static void
pidlist_add_pid(pidlist_t * pl,pid_t pid)2908 pidlist_add_pid(pidlist_t *pl, pid_t pid)
2909 {
2910 	pidlist_entry_t *pe = pl->pl_active;
2911 	if (pe->pe_nused >= sizeof(pe->pe_pid) / sizeof(pe->pe_pid[0])) {
2912 		if (NULL == (pe = SLIST_NEXT(pe, pe_link))) {
2913 			panic("pidlist allocation exhausted");
2914 		}
2915 		pl->pl_active = pe;
2916 	}
2917 	pe->pe_pid[pe->pe_nused++] = pid;
2918 }
2919 
2920 static __inline__ u_int
pidlist_nalloc(const pidlist_t * pl)2921 pidlist_nalloc(const pidlist_t *pl)
2922 {
2923 	return pl->pl_nalloc;
2924 }
2925 
2926 /*
2927  * A process group has become orphaned; if there are any stopped processes in
2928  * the group, hang-up all process in that group.
2929  */
2930 static void
orphanpg(struct pgrp * pgrp)2931 orphanpg(struct pgrp *pgrp)
2932 {
2933 	pidlist_t pid_list, *pl = pidlist_init(&pid_list);
2934 	u_int pid_count_available = 0;
2935 	proc_t p;
2936 
2937 	/* allocate outside of the pgrp_lock */
2938 	for (;;) {
2939 		pgrp_lock(pgrp);
2940 
2941 		boolean_t should_iterate = FALSE;
2942 		pid_count_available = 0;
2943 
2944 		PGMEMBERS_FOREACH(pgrp, p) {
2945 			pid_count_available++;
2946 			if (p->p_stat == SSTOP) {
2947 				should_iterate = TRUE;
2948 			}
2949 		}
2950 		if (pid_count_available == 0 || !should_iterate) {
2951 			pgrp_unlock(pgrp);
2952 			goto out; /* no orphaned processes OR nothing stopped */
2953 		}
2954 		if (pidlist_nalloc(pl) >= pid_count_available) {
2955 			break;
2956 		}
2957 		pgrp_unlock(pgrp);
2958 
2959 		pidlist_alloc(pl, pid_count_available);
2960 	}
2961 	pidlist_set_active(pl);
2962 
2963 	u_int pid_count = 0;
2964 	PGMEMBERS_FOREACH(pgrp, p) {
2965 		pidlist_add_pid(pl, proc_pid(p));
2966 		if (++pid_count >= pid_count_available) {
2967 			break;
2968 		}
2969 	}
2970 	pgrp_unlock(pgrp);
2971 
2972 	const pidlist_entry_t *pe;
2973 	SLIST_FOREACH(pe, &(pl->pl_head), pe_link) {
2974 		for (u_int i = 0; i < pe->pe_nused; i++) {
2975 			const pid_t pid = pe->pe_pid[i];
2976 			if (0 == pid) {
2977 				continue; /* skip kernproc */
2978 			}
2979 			p = proc_find(pid);
2980 			if (!p) {
2981 				continue;
2982 			}
2983 			proc_transwait(p, 0);
2984 			pt_setrunnable(p);
2985 			psignal(p, SIGHUP);
2986 			psignal(p, SIGCONT);
2987 			proc_rele(p);
2988 		}
2989 	}
2990 out:
2991 	pidlist_free(pl);
2992 }
2993 
2994 boolean_t
proc_is_translated(proc_t p)2995 proc_is_translated(proc_t p)
2996 {
2997 	return p && ((p->p_flag & P_TRANSLATED) != 0);
2998 }
2999 
3000 
3001 int
proc_is_classic(proc_t p __unused)3002 proc_is_classic(proc_t p __unused)
3003 {
3004 	return 0;
3005 }
3006 
3007 bool
proc_is_exotic(proc_t p)3008 proc_is_exotic(
3009 	proc_t p)
3010 {
3011 	if (p == NULL) {
3012 		return false;
3013 	}
3014 	return task_is_exotic(proc_task(p));
3015 }
3016 
3017 bool
proc_is_alien(proc_t p)3018 proc_is_alien(
3019 	proc_t p)
3020 {
3021 	if (p == NULL) {
3022 		return false;
3023 	}
3024 	return task_is_alien(proc_task(p));
3025 }
3026 
3027 bool
proc_is_driver(proc_t p)3028 proc_is_driver(proc_t p)
3029 {
3030 	if (p == NULL) {
3031 		return false;
3032 	}
3033 	return task_is_driver(proc_task(p));
3034 }
3035 
3036 bool
proc_is_third_party_debuggable_driver(proc_t p)3037 proc_is_third_party_debuggable_driver(proc_t p)
3038 {
3039 #if XNU_TARGET_OS_IOS
3040 	uint64_t csflags;
3041 	if (proc_csflags(p, &csflags) != 0) {
3042 		return false;
3043 	}
3044 
3045 	if (proc_is_driver(p) &&
3046 	    !csproc_get_platform_binary(p) &&
3047 	    IOTaskHasEntitlement(proc_task(p), kIODriverKitEntitlementKey) &&
3048 	    (csflags & CS_GET_TASK_ALLOW) != 0) {
3049 		return true;
3050 	}
3051 
3052 	return false;
3053 
3054 #else
3055 	/* On other platforms, fall back to existing rules for debugging */
3056 	(void)p;
3057 	return false;
3058 #endif /* XNU_TARGET_OS_IOS */
3059 }
3060 
3061 /* XXX Why does this function exist?  Need to kill it off... */
3062 proc_t
current_proc_EXTERNAL(void)3063 current_proc_EXTERNAL(void)
3064 {
3065 	return current_proc();
3066 }
3067 
3068 int
proc_is_forcing_hfs_case_sensitivity(proc_t p)3069 proc_is_forcing_hfs_case_sensitivity(proc_t p)
3070 {
3071 	return (p->p_vfs_iopolicy & P_VFS_IOPOLICY_FORCE_HFS_CASE_SENSITIVITY) ? 1 : 0;
3072 }
3073 
3074 bool
proc_ignores_content_protection(proc_t p)3075 proc_ignores_content_protection(proc_t p)
3076 {
3077 	return os_atomic_load(&p->p_vfs_iopolicy, relaxed) & P_VFS_IOPOLICY_IGNORE_CONTENT_PROTECTION;
3078 }
3079 
3080 bool
proc_ignores_node_permissions(proc_t p)3081 proc_ignores_node_permissions(proc_t p)
3082 {
3083 	return os_atomic_load(&p->p_vfs_iopolicy, relaxed) & P_VFS_IOPOLICY_IGNORE_NODE_PERMISSIONS;
3084 }
3085 
3086 bool
proc_skip_mtime_update(proc_t p)3087 proc_skip_mtime_update(proc_t p)
3088 {
3089 	struct uthread *ut = NULL;
3090 
3091 	/*
3092 	 * We only check the thread's policy if the current proc matches the given
3093 	 * proc.
3094 	 */
3095 	if (current_proc() == p) {
3096 		ut = get_bsdthread_info(current_thread());
3097 	}
3098 
3099 	if (ut && (os_atomic_load(&ut->uu_flag, relaxed) & UT_SKIP_MTIME_UPDATE)) {
3100 		return true;
3101 	}
3102 
3103 	/*
3104 	 * If the 'UT_SKIP_MTIME_UPDATE_IGNORE' policy is set for this thread then
3105 	 * we override the default behavior and ignore the process's mtime update
3106 	 * policy.
3107 	 */
3108 	if (ut && (os_atomic_load(&ut->uu_flag, relaxed) & UT_SKIP_MTIME_UPDATE_IGNORE)) {
3109 		return false;
3110 	}
3111 
3112 	if (p && (os_atomic_load(&p->p_vfs_iopolicy, relaxed) & P_VFS_IOPOLICY_SKIP_MTIME_UPDATE)) {
3113 		return true;
3114 	}
3115 
3116 	return false;
3117 }
3118 
3119 bool
proc_support_long_paths(proc_t p)3120 proc_support_long_paths(proc_t p)
3121 {
3122 	struct uthread *ut = NULL;
3123 
3124 	/*
3125 	 * We only check the thread's policy if the current proc matches the given
3126 	 * proc.
3127 	 */
3128 	if (current_proc() == p) {
3129 		ut = get_bsdthread_info(current_thread());
3130 	}
3131 
3132 	if (ut != NULL && (os_atomic_load(&ut->uu_flag, relaxed) & UT_SUPPORT_LONG_PATHS)) {
3133 		return true;
3134 	}
3135 
3136 	if (p && (os_atomic_load(&p->p_vfs_iopolicy, relaxed) & P_VFS_IOPOLICY_SUPPORT_LONG_PATHS)) {
3137 		return true;
3138 	}
3139 
3140 	return false;
3141 }
3142 
3143 bool
proc_allow_low_space_writes(proc_t p)3144 proc_allow_low_space_writes(proc_t p)
3145 {
3146 	return os_atomic_load(&p->p_vfs_iopolicy, relaxed) & P_VFS_IOPOLICY_ALLOW_LOW_SPACE_WRITES;
3147 }
3148 
3149 bool
proc_disallow_rw_for_o_evtonly(proc_t p)3150 proc_disallow_rw_for_o_evtonly(proc_t p)
3151 {
3152 	return os_atomic_load(&p->p_vfs_iopolicy, relaxed) & P_VFS_IOPOLICY_DISALLOW_RW_FOR_O_EVTONLY;
3153 }
3154 
3155 bool
proc_use_alternative_symlink_ea(proc_t p)3156 proc_use_alternative_symlink_ea(proc_t p)
3157 {
3158 	return os_atomic_load(&p->p_vfs_iopolicy, relaxed) & P_VFS_IOPOLICY_ALTLINK;
3159 }
3160 
3161 bool
proc_is_rsr(proc_t p)3162 proc_is_rsr(proc_t p)
3163 {
3164 	return os_atomic_load(&p->p_ladvflag, relaxed) & P_RSR;
3165 }
3166 
3167 #if CONFIG_COREDUMP
3168 /*
3169  * proc_core_name(format, name, uid, pid)
3170  * Expand the name described in format, using name, uid, and pid.
3171  * format is a printf-like string, with four format specifiers:
3172  *	%N	name of process ("name")
3173  *	%P	process id (pid)
3174  *	%U	user id (uid)
3175  *	%T  mach_continuous_time() timestamp
3176  * For example, "%N.core" is the default; they can be disabled completely
3177  * by using "/dev/null", or all core files can be stored in "/cores/%U/%N-%P".
3178  * This is controlled by the sysctl variable kern.corefile (see above).
3179  */
3180 __private_extern__ int
proc_core_name(const char * format,const char * name,uid_t uid,pid_t pid,char * cf_name,size_t cf_name_len)3181 proc_core_name(const char *format, const char * name, uid_t uid, pid_t pid, char *cf_name,
3182     size_t cf_name_len)
3183 {
3184 	const char *appendstr;
3185 	char id_buf[sizeof(OS_STRINGIFY(INT32_MAX))];          /* Buffer for pid/uid -- max 4B */
3186 	_Static_assert(sizeof(id_buf) == 11, "size mismatch");
3187 	char timestamp_buf[sizeof(OS_STRINGIFY(UINT64_MAX))];  /* Buffer for timestamp, including null terminator */
3188 	clock_sec_t secs = 0;
3189 	_Static_assert(sizeof(clock_sec_t) <= sizeof(uint64_t), "size mismatch");
3190 	clock_usec_t microsecs = 0;
3191 	size_t i, l, n;
3192 
3193 	if (cf_name == NULL) {
3194 		goto toolong;
3195 	}
3196 
3197 	for (i = 0, n = 0; n < cf_name_len && format[i]; i++) {
3198 		switch (format[i]) {
3199 		case '%':       /* Format character */
3200 			i++;
3201 			switch (format[i]) {
3202 			case '%':
3203 				appendstr = "%";
3204 				break;
3205 			case 'N':       /* process name */
3206 				appendstr = name;
3207 				break;
3208 			case 'P':       /* process id */
3209 				snprintf(id_buf, sizeof(id_buf), "%u", pid);
3210 				appendstr = id_buf;
3211 				break;
3212 			case 'U':       /* user id */
3213 				snprintf(id_buf, sizeof(id_buf), "%u", uid);
3214 				appendstr = id_buf;
3215 				break;
3216 			case 'T':       /* MCT timestamp */
3217 				snprintf(timestamp_buf, sizeof(timestamp_buf), "%llu", mach_continuous_time());
3218 				appendstr = timestamp_buf;
3219 				break;
3220 			case 't':       /* Unix timestamp */
3221 				clock_gettimeofday(&secs, &microsecs);
3222 				snprintf(timestamp_buf, sizeof(timestamp_buf), "%lu", secs);
3223 				appendstr = timestamp_buf;
3224 				break;
3225 			case '\0': /* format string ended in % symbol */
3226 				goto endofstring;
3227 			default:
3228 				appendstr = "";
3229 				log(LOG_ERR,
3230 				    "Unknown format character %c in `%s'\n",
3231 				    format[i], format);
3232 			}
3233 			l = strlen(appendstr);
3234 			if ((n + l) >= cf_name_len) {
3235 				goto toolong;
3236 			}
3237 			bcopy(appendstr, cf_name + n, l);
3238 			n += l;
3239 			break;
3240 		default:
3241 			cf_name[n++] = format[i];
3242 		}
3243 	}
3244 	if (format[i] != '\0') {
3245 		goto toolong;
3246 	}
3247 	return 0;
3248 toolong:
3249 	log(LOG_ERR, "pid %ld (%s), uid (%u): corename is too long\n",
3250 	    (long)pid, name, (uint32_t)uid);
3251 	return 1;
3252 endofstring:
3253 	log(LOG_ERR, "pid %ld (%s), uid (%u): unexpected end of string after %% token\n",
3254 	    (long)pid, name, (uint32_t)uid);
3255 	return 1;
3256 }
3257 #endif /* CONFIG_COREDUMP */
3258 
3259 /* Code Signing related routines */
3260 
3261 int
csops(__unused proc_t p,struct csops_args * uap,__unused int32_t * retval)3262 csops(__unused proc_t p, struct csops_args *uap, __unused int32_t *retval)
3263 {
3264 	return csops_internal(uap->pid, uap->ops, uap->useraddr,
3265 	           uap->usersize, USER_ADDR_NULL);
3266 }
3267 
3268 int
csops_audittoken(__unused proc_t p,struct csops_audittoken_args * uap,__unused int32_t * retval)3269 csops_audittoken(__unused proc_t p, struct csops_audittoken_args *uap, __unused int32_t *retval)
3270 {
3271 	if (uap->uaudittoken == USER_ADDR_NULL) {
3272 		return EINVAL;
3273 	}
3274 	return csops_internal(uap->pid, uap->ops, uap->useraddr,
3275 	           uap->usersize, uap->uaudittoken);
3276 }
3277 
3278 static int
csops_copy_token(const void * start,size_t length,user_size_t usize,user_addr_t uaddr)3279 csops_copy_token(const void *start, size_t length, user_size_t usize, user_addr_t uaddr)
3280 {
3281 	char fakeheader[8] = { 0 };
3282 	int error;
3283 
3284 	if (usize < sizeof(fakeheader)) {
3285 		return ERANGE;
3286 	}
3287 
3288 	/* if no blob, fill in zero header */
3289 	if (NULL == start) {
3290 		start = fakeheader;
3291 		length = sizeof(fakeheader);
3292 	} else if (usize < length) {
3293 		/* ... if input too short, copy out length of entitlement */
3294 		uint32_t length32 = htonl((uint32_t)length);
3295 		memcpy(&fakeheader[4], &length32, sizeof(length32));
3296 
3297 		error = copyout(fakeheader, uaddr, sizeof(fakeheader));
3298 		if (error == 0) {
3299 			return ERANGE; /* input buffer to short, ERANGE signals that */
3300 		}
3301 		return error;
3302 	}
3303 	return copyout(start, uaddr, length);
3304 }
3305 
3306 static int
csops_internal(pid_t pid,int ops,user_addr_t uaddr,user_size_t usersize,user_addr_t uaudittoken)3307 csops_internal(pid_t pid, int ops, user_addr_t uaddr, user_size_t usersize, user_addr_t uaudittoken)
3308 {
3309 	size_t usize = (size_t)CAST_DOWN(size_t, usersize);
3310 	proc_t pt;
3311 	int forself;
3312 	int error;
3313 	vnode_t tvp;
3314 	off_t toff;
3315 	csops_cdhash_t cdhash_info = {0};
3316 	audit_token_t token;
3317 	unsigned int upid = 0, uidversion = 0;
3318 	bool mark_invalid_allowed = false;
3319 
3320 	forself = error = 0;
3321 
3322 	if (pid == 0) {
3323 		pid = proc_selfpid();
3324 	}
3325 	if (pid == proc_selfpid()) {
3326 		forself = 1;
3327 		mark_invalid_allowed = true;
3328 	}
3329 
3330 	switch (ops) {
3331 	case CS_OPS_STATUS:
3332 	case CS_OPS_CDHASH:
3333 	case CS_OPS_CDHASH_WITH_INFO:
3334 	case CS_OPS_PIDOFFSET:
3335 	case CS_OPS_ENTITLEMENTS_BLOB:
3336 	case CS_OPS_DER_ENTITLEMENTS_BLOB:
3337 	case CS_OPS_IDENTITY:
3338 	case CS_OPS_BLOB:
3339 	case CS_OPS_TEAMID:
3340 	case CS_OPS_CLEAR_LV:
3341 	case CS_OPS_VALIDATION_CATEGORY:
3342 		break;          /* not restricted to root */
3343 	default:
3344 		if (forself == 0 && kauth_cred_issuser(kauth_cred_get()) != TRUE) {
3345 			return EPERM;
3346 		}
3347 		break;
3348 	}
3349 
3350 	pt = proc_find(pid);
3351 	if (pt == PROC_NULL) {
3352 		return ESRCH;
3353 	}
3354 
3355 	upid = proc_getpid(pt);
3356 	uidversion = proc_pidversion(pt);
3357 	if (uaudittoken != USER_ADDR_NULL) {
3358 		error = copyin(uaudittoken, &token, sizeof(audit_token_t));
3359 		if (error != 0) {
3360 			goto out;
3361 		}
3362 		/* verify the audit token pid/idversion matches with proc */
3363 		if ((token.val[5] != upid) || (token.val[7] != uidversion)) {
3364 			error = ESRCH;
3365 			goto out;
3366 		}
3367 	}
3368 
3369 #if CONFIG_MACF
3370 	switch (ops) {
3371 	case CS_OPS_MARKINVALID:
3372 	case CS_OPS_MARKHARD:
3373 	case CS_OPS_MARKKILL:
3374 	case CS_OPS_MARKRESTRICT:
3375 	case CS_OPS_SET_STATUS:
3376 	case CS_OPS_CLEARINSTALLER:
3377 	case CS_OPS_CLEARPLATFORM:
3378 	case CS_OPS_CLEAR_LV:
3379 		if ((error = mac_proc_check_set_cs_info(current_proc(), pt, ops))) {
3380 			goto out;
3381 		}
3382 		break;
3383 	default:
3384 		if ((error = mac_proc_check_get_cs_info(current_proc(), pt, ops))) {
3385 			goto out;
3386 		}
3387 	}
3388 #endif
3389 
3390 	switch (ops) {
3391 	case CS_OPS_STATUS: {
3392 		uint32_t retflags;
3393 
3394 		proc_lock(pt);
3395 		retflags = (uint32_t)proc_getcsflags(pt);
3396 		if (cs_process_enforcement(pt)) {
3397 			retflags |= CS_ENFORCEMENT;
3398 		}
3399 		if (csproc_get_platform_binary(pt)) {
3400 			retflags |= CS_PLATFORM_BINARY;
3401 		}
3402 		if (csproc_get_platform_path(pt)) {
3403 			retflags |= CS_PLATFORM_PATH;
3404 		}
3405 		//Don't return CS_REQUIRE_LV if we turned it on with CS_FORCED_LV but still report CS_FORCED_LV
3406 		if ((proc_getcsflags(pt) & CS_FORCED_LV) == CS_FORCED_LV) {
3407 			retflags &= (~CS_REQUIRE_LV);
3408 		}
3409 		proc_unlock(pt);
3410 
3411 		if (uaddr != USER_ADDR_NULL) {
3412 			error = copyout(&retflags, uaddr, sizeof(uint32_t));
3413 		}
3414 		break;
3415 	}
3416 	case CS_OPS_MARKINVALID:
3417 		if (mark_invalid_allowed == false) {
3418 			error = EPERM;
3419 			goto out;
3420 		}
3421 		proc_lock(pt);
3422 		if ((proc_getcsflags(pt) & CS_VALID) == CS_VALID) {           /* is currently valid */
3423 			proc_csflags_clear(pt, CS_VALID);       /* set invalid */
3424 			cs_process_invalidated(pt);
3425 			if ((proc_getcsflags(pt) & CS_KILL) == CS_KILL) {
3426 				proc_csflags_set(pt, CS_KILLED);
3427 				proc_unlock(pt);
3428 				if (cs_debug) {
3429 					printf("CODE SIGNING: marked invalid by pid %d: "
3430 					    "p=%d[%s] honoring CS_KILL, final status 0x%x\n",
3431 					    proc_selfpid(), proc_getpid(pt), pt->p_comm,
3432 					    (unsigned int)proc_getcsflags(pt));
3433 				}
3434 				psignal(pt, SIGKILL);
3435 			} else {
3436 				proc_unlock(pt);
3437 			}
3438 		} else {
3439 			proc_unlock(pt);
3440 		}
3441 
3442 		break;
3443 
3444 	case CS_OPS_MARKHARD:
3445 		proc_lock(pt);
3446 		proc_csflags_set(pt, CS_HARD);
3447 		if ((proc_getcsflags(pt) & CS_VALID) == 0) {
3448 			/* @@@ allow? reject? kill? @@@ */
3449 			proc_unlock(pt);
3450 			error = EINVAL;
3451 			goto out;
3452 		} else {
3453 			proc_unlock(pt);
3454 		}
3455 		break;
3456 
3457 	case CS_OPS_MARKKILL:
3458 		proc_lock(pt);
3459 		proc_csflags_set(pt, CS_KILL);
3460 		if ((proc_getcsflags(pt) & CS_VALID) == 0) {
3461 			proc_unlock(pt);
3462 			psignal(pt, SIGKILL);
3463 		} else {
3464 			proc_unlock(pt);
3465 		}
3466 		break;
3467 
3468 	case CS_OPS_PIDOFFSET:
3469 		toff = pt->p_textoff;
3470 		proc_rele(pt);
3471 		error = copyout(&toff, uaddr, sizeof(toff));
3472 		return error;
3473 
3474 	case CS_OPS_CDHASH:
3475 
3476 		/* pt already holds a reference on its p_textvp */
3477 		tvp = pt->p_textvp;
3478 		toff = pt->p_textoff;
3479 
3480 		if (tvp == NULLVP || usize != sizeof(cdhash_info.hash)) {
3481 			proc_rele(pt);
3482 			return EINVAL;
3483 		}
3484 
3485 		error = vn_getcdhash(tvp, toff, cdhash_info.hash, &cdhash_info.type);
3486 		proc_rele(pt);
3487 
3488 		if (error == 0) {
3489 			error = copyout(cdhash_info.hash, uaddr, sizeof(cdhash_info.hash));
3490 		}
3491 
3492 		return error;
3493 
3494 	case CS_OPS_CDHASH_WITH_INFO:
3495 
3496 		/* pt already holds a reference on its p_textvp */
3497 		tvp = pt->p_textvp;
3498 		toff = pt->p_textoff;
3499 
3500 		if (tvp == NULLVP || usize != sizeof(csops_cdhash_t)) {
3501 			proc_rele(pt);
3502 			return EINVAL;
3503 		}
3504 
3505 		error = vn_getcdhash(tvp, toff, cdhash_info.hash, &cdhash_info.type);
3506 		proc_rele(pt);
3507 
3508 		if (error == 0) {
3509 			error = copyout(&cdhash_info, uaddr, sizeof(cdhash_info));
3510 		}
3511 
3512 		return error;
3513 
3514 	case CS_OPS_ENTITLEMENTS_BLOB: {
3515 		void *start;
3516 		size_t length;
3517 		struct cs_blob* blob;
3518 
3519 		proc_lock(pt);
3520 		if ((proc_getcsflags(pt) & (CS_VALID | CS_DEBUGGED)) == 0) {
3521 			proc_unlock(pt);
3522 			error = EINVAL;
3523 			goto out;
3524 		}
3525 		blob = csproc_get_blob(pt);
3526 		proc_unlock(pt);
3527 
3528 		if (!blob) {
3529 			error = EBADEXEC;
3530 			goto out;
3531 		}
3532 
3533 		void* osent = csblob_os_entitlements_get(blob);
3534 		if (!osent) {
3535 			goto out;
3536 		}
3537 		CS_GenericBlob* xmlblob = NULL;
3538 		if (amfi->OSEntitlements_get_xml(osent, &xmlblob)) {
3539 			start = (void*)xmlblob;
3540 			length = (size_t)ntohl(xmlblob->length);
3541 		} else {
3542 			goto out;
3543 		}
3544 
3545 		error = csops_copy_token(start, length, usize, uaddr);
3546 		kfree_data(start, length);
3547 		goto out;
3548 	}
3549 	case CS_OPS_DER_ENTITLEMENTS_BLOB: {
3550 		const void *start;
3551 		size_t length;
3552 		struct cs_blob* blob;
3553 
3554 		proc_lock(pt);
3555 		if ((proc_getcsflags(pt) & (CS_VALID | CS_DEBUGGED)) == 0) {
3556 			proc_unlock(pt);
3557 			error = EINVAL;
3558 			goto out;
3559 		}
3560 		blob = csproc_get_blob(pt);
3561 		proc_unlock(pt);
3562 
3563 		if (!blob) {
3564 			error = EBADEXEC;
3565 			goto out;
3566 		}
3567 
3568 		error = csblob_get_der_entitlements(blob, (const CS_GenericBlob **)&start, &length);
3569 		if (error || start == NULL) {
3570 			if (amfi && csblob_os_entitlements_get(blob)) {
3571 				void* osent = csblob_os_entitlements_get(blob);
3572 
3573 				const CS_GenericBlob* transmuted = NULL;
3574 				if (amfi->OSEntitlements_get_transmuted(osent, &transmuted)) {
3575 					start = transmuted;
3576 					length = (size_t)ntohl(transmuted->length);
3577 				} else {
3578 					goto out;
3579 				}
3580 			} else {
3581 				goto out;
3582 			}
3583 		}
3584 
3585 		error = csops_copy_token(start, length, usize, uaddr);
3586 		goto out;
3587 	}
3588 
3589 	case CS_OPS_VALIDATION_CATEGORY:
3590 	{
3591 		unsigned int validation_category = CS_VALIDATION_CATEGORY_INVALID;
3592 		error = csproc_get_validation_category(pt, &validation_category);
3593 		if (error) {
3594 			goto out;
3595 		}
3596 		error = copyout(&validation_category, uaddr, sizeof(validation_category));
3597 		break;
3598 	}
3599 
3600 	case CS_OPS_MARKRESTRICT:
3601 		proc_lock(pt);
3602 		proc_csflags_set(pt, CS_RESTRICT);
3603 		proc_unlock(pt);
3604 		break;
3605 
3606 	case CS_OPS_SET_STATUS: {
3607 		uint32_t flags;
3608 
3609 		if (usize < sizeof(flags)) {
3610 			error = ERANGE;
3611 			break;
3612 		}
3613 
3614 		error = copyin(uaddr, &flags, sizeof(flags));
3615 		if (error) {
3616 			break;
3617 		}
3618 
3619 		/* only allow setting a subset of all code sign flags */
3620 		flags &=
3621 		    CS_HARD | CS_EXEC_SET_HARD |
3622 		    CS_KILL | CS_EXEC_SET_KILL |
3623 		    CS_RESTRICT |
3624 		    CS_REQUIRE_LV |
3625 		    CS_ENFORCEMENT | CS_EXEC_SET_ENFORCEMENT;
3626 
3627 		proc_lock(pt);
3628 		if (proc_getcsflags(pt) & CS_VALID) {
3629 			if ((flags & CS_ENFORCEMENT) &&
3630 			    !(proc_getcsflags(pt) & CS_ENFORCEMENT)) {
3631 				vm_map_cs_enforcement_set(get_task_map(proc_task(pt)), TRUE);
3632 			}
3633 			proc_csflags_set(pt, flags);
3634 		} else {
3635 			error = EINVAL;
3636 		}
3637 		proc_unlock(pt);
3638 
3639 		break;
3640 	}
3641 	case CS_OPS_CLEAR_LV: {
3642 		/*
3643 		 * This option is used to remove library validation from
3644 		 * a running process. This is used in plugin architectures
3645 		 * when a program needs to load untrusted libraries. This
3646 		 * allows the process to maintain library validation as
3647 		 * long as possible, then drop it only when required.
3648 		 * Once a process has loaded the untrusted library,
3649 		 * relying on library validation in the future will
3650 		 * not be effective. An alternative is to re-exec
3651 		 * your application without library validation, or
3652 		 * fork an untrusted child.
3653 		 */
3654 #if !defined(XNU_TARGET_OS_OSX)
3655 		// We only support dropping library validation on macOS
3656 		error = ENOTSUP;
3657 #else
3658 		/*
3659 		 * if we have the flag set, and the caller wants
3660 		 * to remove it, and they're entitled to, then
3661 		 * we remove it from the csflags
3662 		 *
3663 		 * NOTE: We are fine to poke into the task because
3664 		 * we get a ref to pt when we do the proc_find
3665 		 * at the beginning of this function.
3666 		 *
3667 		 * We also only allow altering ourselves.
3668 		 */
3669 		if (forself == 1 && IOTaskHasEntitlement(proc_task(pt), CLEAR_LV_ENTITLEMENT)) {
3670 			proc_lock(pt);
3671 			if (!(proc_getcsflags(pt) & CS_INSTALLER) && (pt->p_subsystem_root_path == NULL)) {
3672 				proc_csflags_clear(pt, CS_REQUIRE_LV | CS_FORCED_LV);
3673 				error = 0;
3674 			} else {
3675 				error = EPERM;
3676 			}
3677 			proc_unlock(pt);
3678 		} else {
3679 			error = EPERM;
3680 		}
3681 #endif
3682 		break;
3683 	}
3684 	case CS_OPS_BLOB: {
3685 		void *start;
3686 		size_t length;
3687 
3688 		proc_lock(pt);
3689 		if ((proc_getcsflags(pt) & (CS_VALID | CS_DEBUGGED)) == 0) {
3690 			proc_unlock(pt);
3691 			error = EINVAL;
3692 			break;
3693 		}
3694 		proc_unlock(pt);
3695 		// Don't need to lock here as not accessing CSFLAGS
3696 		error = cs_blob_get(pt, &start, &length);
3697 		if (error) {
3698 			goto out;
3699 		}
3700 
3701 		error = csops_copy_token(start, length, usize, uaddr);
3702 		goto out;
3703 	}
3704 	case CS_OPS_IDENTITY:
3705 	case CS_OPS_TEAMID: {
3706 		const char *identity;
3707 		uint8_t fakeheader[8];
3708 		uint32_t idlen;
3709 		size_t length;
3710 
3711 		/*
3712 		 * Make identity have a blob header to make it
3713 		 * easier on userland to guess the identity
3714 		 * length.
3715 		 */
3716 		if (usize < sizeof(fakeheader)) {
3717 			error = ERANGE;
3718 			break;
3719 		}
3720 		memset(fakeheader, 0, sizeof(fakeheader));
3721 
3722 		proc_lock(pt);
3723 		if ((proc_getcsflags(pt) & (CS_VALID | CS_DEBUGGED)) == 0) {
3724 			proc_unlock(pt);
3725 			error = EINVAL;
3726 			break;
3727 		}
3728 		identity = ops == CS_OPS_TEAMID ? csproc_get_teamid(pt) : cs_identity_get(pt);
3729 		proc_unlock(pt);
3730 
3731 		if (identity == NULL) {
3732 			error = ENOENT;
3733 			goto out;
3734 		}
3735 
3736 		length = strlen(identity) + 1;         /* include NUL */
3737 		idlen = htonl((uint32_t)(length + sizeof(fakeheader)));
3738 		memcpy(&fakeheader[4], &idlen, sizeof(idlen));
3739 
3740 		error = copyout(fakeheader, uaddr, sizeof(fakeheader));
3741 		if (error) {
3742 			goto out;
3743 		}
3744 
3745 		if (usize < sizeof(fakeheader) + length) {
3746 			error = ERANGE;
3747 		} else if (usize > sizeof(fakeheader)) {
3748 			error = copyout(identity, uaddr + sizeof(fakeheader), length);
3749 		}
3750 		goto out;
3751 	}
3752 
3753 	case CS_OPS_CLEARINSTALLER:
3754 		proc_lock(pt);
3755 		proc_csflags_clear(pt, CS_INSTALLER | CS_DATAVAULT_CONTROLLER | CS_EXEC_INHERIT_SIP);
3756 		proc_unlock(pt);
3757 		break;
3758 
3759 	case CS_OPS_CLEARPLATFORM:
3760 #if DEVELOPMENT || DEBUG
3761 		if (cs_process_global_enforcement()) {
3762 			error = ENOTSUP;
3763 			break;
3764 		}
3765 
3766 #if CONFIG_CSR
3767 		if (csr_check(CSR_ALLOW_APPLE_INTERNAL) != 0) {
3768 			error = ENOTSUP;
3769 			break;
3770 		}
3771 #endif /* CONFIG_CSR */
3772 		task_t task = proc_task(pt);
3773 
3774 		proc_lock(pt);
3775 		proc_csflags_clear(pt, CS_PLATFORM_BINARY | CS_PLATFORM_PATH);
3776 		task_set_hardened_runtime(task, false);
3777 		csproc_clear_platform_binary(pt);
3778 		proc_unlock(pt);
3779 		break;
3780 #else  /* DEVELOPMENT || DEBUG */
3781 		error = ENOTSUP;
3782 		break;
3783 #endif /* !DEVELOPMENT || DEBUG */
3784 
3785 	default:
3786 		error = EINVAL;
3787 		break;
3788 	}
3789 out:
3790 	proc_rele(pt);
3791 	return error;
3792 }
3793 
3794 void
proc_iterate(unsigned int flags,proc_iterate_fn_t callout,void * arg,proc_iterate_fn_t filterfn,void * filterarg)3795 proc_iterate(
3796 	unsigned int flags,
3797 	proc_iterate_fn_t callout,
3798 	void *arg,
3799 	proc_iterate_fn_t filterfn,
3800 	void *filterarg)
3801 {
3802 	pidlist_t pid_list, *pl = pidlist_init(&pid_list);
3803 	u_int pid_count_available = 0;
3804 
3805 	assert(callout != NULL);
3806 
3807 	/* allocate outside of the proc_list_lock */
3808 	for (;;) {
3809 		proc_list_lock();
3810 		pid_count_available = nprocs + 1; /* kernel_task not counted in nprocs */
3811 		assert(pid_count_available > 0);
3812 		if (pidlist_nalloc(pl) >= pid_count_available) {
3813 			break;
3814 		}
3815 		proc_list_unlock();
3816 
3817 		pidlist_alloc(pl, pid_count_available);
3818 	}
3819 	pidlist_set_active(pl);
3820 
3821 	/* filter pids into the pid_list */
3822 
3823 	u_int pid_count = 0;
3824 	if (flags & PROC_ALLPROCLIST) {
3825 		proc_t p;
3826 		ALLPROC_FOREACH(p) {
3827 			/* ignore processes that are being forked */
3828 			if (p->p_stat == SIDL || proc_is_shadow(p)) {
3829 				continue;
3830 			}
3831 			if ((filterfn != NULL) && (filterfn(p, filterarg) == 0)) {
3832 				continue;
3833 			}
3834 			pidlist_add_pid(pl, proc_pid(p));
3835 			if (++pid_count >= pid_count_available) {
3836 				break;
3837 			}
3838 		}
3839 	}
3840 
3841 	if ((pid_count < pid_count_available) &&
3842 	    (flags & PROC_ZOMBPROCLIST)) {
3843 		proc_t p;
3844 		ZOMBPROC_FOREACH(p) {
3845 			if (proc_is_shadow(p)) {
3846 				continue;
3847 			}
3848 			if ((filterfn != NULL) && (filterfn(p, filterarg) == 0)) {
3849 				continue;
3850 			}
3851 			pidlist_add_pid(pl, proc_pid(p));
3852 			if (++pid_count >= pid_count_available) {
3853 				break;
3854 			}
3855 		}
3856 	}
3857 
3858 	proc_list_unlock();
3859 
3860 	/* call callout on processes in the pid_list */
3861 
3862 	const pidlist_entry_t *pe;
3863 	SLIST_FOREACH(pe, &(pl->pl_head), pe_link) {
3864 		for (u_int i = 0; i < pe->pe_nused; i++) {
3865 			const pid_t pid = pe->pe_pid[i];
3866 			proc_t p = proc_find(pid);
3867 			if (p) {
3868 				if ((flags & PROC_NOWAITTRANS) == 0) {
3869 					proc_transwait(p, 0);
3870 				}
3871 				const int callout_ret = callout(p, arg);
3872 
3873 				switch (callout_ret) {
3874 				case PROC_RETURNED_DONE:
3875 					proc_rele(p);
3876 					OS_FALLTHROUGH;
3877 				case PROC_CLAIMED_DONE:
3878 					goto out;
3879 
3880 				case PROC_RETURNED:
3881 					proc_rele(p);
3882 					OS_FALLTHROUGH;
3883 				case PROC_CLAIMED:
3884 					break;
3885 				default:
3886 					panic("%s: callout =%d for pid %d",
3887 					    __func__, callout_ret, pid);
3888 					break;
3889 				}
3890 			} else if (flags & PROC_ZOMBPROCLIST) {
3891 				p = proc_find_zombref(pid);
3892 				if (!p) {
3893 					continue;
3894 				}
3895 				const int callout_ret = callout(p, arg);
3896 
3897 				switch (callout_ret) {
3898 				case PROC_RETURNED_DONE:
3899 					proc_drop_zombref(p);
3900 					OS_FALLTHROUGH;
3901 				case PROC_CLAIMED_DONE:
3902 					goto out;
3903 
3904 				case PROC_RETURNED:
3905 					proc_drop_zombref(p);
3906 					OS_FALLTHROUGH;
3907 				case PROC_CLAIMED:
3908 					break;
3909 				default:
3910 					panic("%s: callout =%d for zombie %d",
3911 					    __func__, callout_ret, pid);
3912 					break;
3913 				}
3914 			}
3915 		}
3916 	}
3917 out:
3918 	pidlist_free(pl);
3919 }
3920 
3921 void
proc_rebootscan(proc_iterate_fn_t callout,void * arg,proc_iterate_fn_t filterfn,void * filterarg)3922 proc_rebootscan(
3923 	proc_iterate_fn_t callout,
3924 	void *arg,
3925 	proc_iterate_fn_t filterfn,
3926 	void *filterarg)
3927 {
3928 	proc_t p;
3929 
3930 	assert(callout != NULL);
3931 
3932 	proc_shutdown_exitcount = 0;
3933 
3934 restart_foreach:
3935 
3936 	proc_list_lock();
3937 
3938 	ALLPROC_FOREACH(p) {
3939 		if ((filterfn != NULL) && filterfn(p, filterarg) == 0) {
3940 			continue;
3941 		}
3942 		p = proc_ref(p, true);
3943 		if (!p) {
3944 			proc_list_unlock();
3945 			goto restart_foreach;
3946 		}
3947 
3948 		proc_list_unlock();
3949 
3950 		proc_transwait(p, 0);
3951 		(void)callout(p, arg);
3952 		proc_rele(p);
3953 
3954 		goto restart_foreach;
3955 	}
3956 
3957 	proc_list_unlock();
3958 }
3959 
3960 void
proc_childrenwalk(proc_t parent,proc_iterate_fn_t callout,void * arg)3961 proc_childrenwalk(
3962 	proc_t parent,
3963 	proc_iterate_fn_t callout,
3964 	void *arg)
3965 {
3966 	pidlist_t pid_list, *pl = pidlist_init(&pid_list);
3967 	u_int pid_count_available = 0;
3968 
3969 	assert(parent != NULL);
3970 	assert(callout != NULL);
3971 
3972 	for (;;) {
3973 		proc_list_lock();
3974 		pid_count_available = parent->p_childrencnt;
3975 		if (pid_count_available == 0) {
3976 			proc_list_unlock();
3977 			goto out;
3978 		}
3979 		if (pidlist_nalloc(pl) >= pid_count_available) {
3980 			break;
3981 		}
3982 		proc_list_unlock();
3983 
3984 		pidlist_alloc(pl, pid_count_available);
3985 	}
3986 	pidlist_set_active(pl);
3987 
3988 	u_int pid_count = 0;
3989 	proc_t p;
3990 	PCHILDREN_FOREACH(parent, p) {
3991 		if (p->p_stat == SIDL || proc_is_shadow(p)) {
3992 			continue;
3993 		}
3994 
3995 		pidlist_add_pid(pl, proc_pid(p));
3996 		if (++pid_count >= pid_count_available) {
3997 			break;
3998 		}
3999 	}
4000 
4001 	proc_list_unlock();
4002 
4003 	const pidlist_entry_t *pe;
4004 	SLIST_FOREACH(pe, &(pl->pl_head), pe_link) {
4005 		for (u_int i = 0; i < pe->pe_nused; i++) {
4006 			const pid_t pid = pe->pe_pid[i];
4007 			p = proc_find(pid);
4008 			if (!p) {
4009 				continue;
4010 			}
4011 			const int callout_ret = callout(p, arg);
4012 
4013 			switch (callout_ret) {
4014 			case PROC_RETURNED_DONE:
4015 				proc_rele(p);
4016 				OS_FALLTHROUGH;
4017 			case PROC_CLAIMED_DONE:
4018 				goto out;
4019 
4020 			case PROC_RETURNED:
4021 				proc_rele(p);
4022 				OS_FALLTHROUGH;
4023 			case PROC_CLAIMED:
4024 				break;
4025 			default:
4026 				panic("%s: callout =%d for pid %d",
4027 				    __func__, callout_ret, pid);
4028 				break;
4029 			}
4030 		}
4031 	}
4032 out:
4033 	pidlist_free(pl);
4034 }
4035 
4036 void
4037 pgrp_iterate(
4038 	struct pgrp *pgrp,
4039 	proc_iterate_fn_t callout,
4040 	void * arg,
4041 	bool (^filterfn)(proc_t))
4042 {
4043 	pidlist_t pid_list, *pl = pidlist_init(&pid_list);
4044 	u_int pid_count_available = 0;
4045 	proc_t p;
4046 
4047 	assert(pgrp != NULL);
4048 	assert(callout != NULL);
4049 
4050 	for (;;) {
4051 		pgrp_lock(pgrp);
4052 		/*
4053 		 * each member has one ref + some transient holders,
4054 		 * this is a good enough approximation
4055 		 */
4056 		pid_count_available = os_ref_get_count_mask(&pgrp->pg_refcount,
4057 		    PGRP_REF_BITS);
4058 		if (pidlist_nalloc(pl) >= pid_count_available) {
4059 			break;
4060 		}
4061 		pgrp_unlock(pgrp);
4062 
4063 		pidlist_alloc(pl, pid_count_available);
4064 	}
4065 	pidlist_set_active(pl);
4066 
4067 	const pid_t pgid = pgrp->pg_id;
4068 	u_int pid_count = 0;
4069 
PGMEMBERS_FOREACH(pgrp,p)4070 	PGMEMBERS_FOREACH(pgrp, p) {
4071 		if ((filterfn != NULL) && (filterfn(p) == 0)) {
4072 			continue;
4073 		}
4074 		pidlist_add_pid(pl, proc_pid(p));
4075 		if (++pid_count >= pid_count_available) {
4076 			break;
4077 		}
4078 	}
4079 
4080 	pgrp_unlock(pgrp);
4081 
4082 	const pidlist_entry_t *pe;
4083 	SLIST_FOREACH(pe, &(pl->pl_head), pe_link) {
4084 		for (u_int i = 0; i < pe->pe_nused; i++) {
4085 			const pid_t pid = pe->pe_pid[i];
4086 			if (0 == pid) {
4087 				continue; /* skip kernproc */
4088 			}
4089 			p = proc_find(pid);
4090 			if (!p) {
4091 				continue;
4092 			}
4093 			if (p->p_pgrpid != pgid) {
4094 				proc_rele(p);
4095 				continue;
4096 			}
4097 			const int callout_ret = callout(p, arg);
4098 
4099 			switch (callout_ret) {
4100 			case PROC_RETURNED:
4101 				proc_rele(p);
4102 				OS_FALLTHROUGH;
4103 			case PROC_CLAIMED:
4104 				break;
4105 			case PROC_RETURNED_DONE:
4106 				proc_rele(p);
4107 				OS_FALLTHROUGH;
4108 			case PROC_CLAIMED_DONE:
4109 				goto out;
4110 
4111 			default:
4112 				panic("%s: callout =%d for pid %d",
4113 				    __func__, callout_ret, pid);
4114 			}
4115 		}
4116 	}
4117 
4118 out:
4119 	pidlist_free(pl);
4120 }
4121 
4122 /* consumes the newpg ref */
4123 static void
pgrp_replace(struct proc * p,struct pgrp * newpg)4124 pgrp_replace(struct proc *p, struct pgrp *newpg)
4125 {
4126 	struct pgrp *oldpg;
4127 
4128 	proc_list_lock();
4129 	oldpg = smr_serialized_load(&p->p_pgrp);
4130 	pgrp_del_member(oldpg, p);
4131 	pgrp_add_member(newpg, PROC_NULL, p);
4132 	proc_list_unlock();
4133 
4134 	pgrp_rele(oldpg);
4135 }
4136 
4137 struct pgrp *
pgrp_alloc(pid_t pgid,pggrp_ref_bits_t bits)4138 pgrp_alloc(pid_t pgid, pggrp_ref_bits_t bits)
4139 {
4140 	struct pgrp *pgrp = zalloc_flags(pgrp_zone, Z_WAITOK | Z_ZERO | Z_NOFAIL);
4141 
4142 	os_ref_init_mask(&pgrp->pg_refcount, PGRP_REF_BITS, &p_refgrp, bits);
4143 	os_ref_init_raw(&pgrp->pg_hashref, &p_refgrp);
4144 	LIST_INIT(&pgrp->pg_members);
4145 	lck_mtx_init(&pgrp->pg_mlock, &proc_mlock_grp, &proc_lck_attr);
4146 	pgrp->pg_id = pgid;
4147 
4148 	return pgrp;
4149 }
4150 
4151 void
pgrp_lock(struct pgrp * pgrp)4152 pgrp_lock(struct pgrp * pgrp)
4153 {
4154 	lck_mtx_lock(&pgrp->pg_mlock);
4155 }
4156 
4157 void
pgrp_unlock(struct pgrp * pgrp)4158 pgrp_unlock(struct pgrp * pgrp)
4159 {
4160 	lck_mtx_unlock(&pgrp->pg_mlock);
4161 }
4162 
4163 struct session *
session_find_locked(pid_t sessid)4164 session_find_locked(pid_t sessid)
4165 {
4166 	struct session *sess;
4167 
4168 	LIST_FOREACH(sess, SESSHASH(sessid), s_hash) {
4169 		if (sess->s_sid == sessid) {
4170 			break;
4171 		}
4172 	}
4173 
4174 	return sess;
4175 }
4176 
4177 void
session_replace_leader(struct proc * old_proc,struct proc * new_proc)4178 session_replace_leader(struct proc *old_proc, struct proc *new_proc)
4179 {
4180 	assert(old_proc == current_proc());
4181 
4182 	/* If old_proc is session leader, change the leader to new proc */
4183 	struct pgrp *pgrp = smr_serialized_load(&old_proc->p_pgrp);
4184 	struct session *sessp = pgrp->pg_session;
4185 	struct tty *ttyp = TTY_NULL;
4186 
4187 	if (sessp == SESSION_NULL || !SESS_LEADER(old_proc, sessp)) {
4188 		return;
4189 	}
4190 
4191 	session_lock(sessp);
4192 	if (sessp->s_ttyp && sessp->s_ttyp->t_session == sessp) {
4193 		ttyp = sessp->s_ttyp;
4194 		ttyhold(ttyp);
4195 	}
4196 
4197 	/* Do the dance to take tty lock and session lock */
4198 	if (ttyp) {
4199 		session_unlock(sessp);
4200 		tty_lock(ttyp);
4201 		session_lock(sessp);
4202 	}
4203 
4204 	sessp->s_leader = new_proc;
4205 	session_unlock(sessp);
4206 
4207 	if (ttyp) {
4208 		tty_unlock(ttyp);
4209 		ttyfree(ttyp);
4210 	}
4211 }
4212 
4213 void
session_lock(struct session * sess)4214 session_lock(struct session * sess)
4215 {
4216 	lck_mtx_lock(&sess->s_mlock);
4217 }
4218 
4219 
4220 void
session_unlock(struct session * sess)4221 session_unlock(struct session * sess)
4222 {
4223 	lck_mtx_unlock(&sess->s_mlock);
4224 }
4225 
4226 struct pgrp *
proc_pgrp(proc_t p,struct session ** sessp)4227 proc_pgrp(proc_t p, struct session **sessp)
4228 {
4229 	struct pgrp *pgrp = PGRP_NULL;
4230 	bool success = false;
4231 
4232 	if (__probable(p != PROC_NULL)) {
4233 		smr_proc_task_enter();
4234 		pgrp = smr_entered_load(&p->p_pgrp);
4235 		success = pgrp == PGRP_NULL || pg_ref_try(pgrp);
4236 		smr_proc_task_leave();
4237 
4238 		if (__improbable(!success)) {
4239 			/*
4240 			 * We caught the process in the middle of pgrp_replace(),
4241 			 * go the slow, never failing way.
4242 			 */
4243 			proc_list_lock();
4244 			pgrp = pg_ref(smr_serialized_load(&p->p_pgrp));
4245 			proc_list_unlock();
4246 		}
4247 	}
4248 
4249 	if (sessp) {
4250 		*sessp = pgrp ? pgrp->pg_session : SESSION_NULL;
4251 	}
4252 	return pgrp;
4253 }
4254 
4255 struct pgrp *
tty_pgrp_locked(struct tty * tp)4256 tty_pgrp_locked(struct tty *tp)
4257 {
4258 	struct pgrp *pg = PGRP_NULL;
4259 
4260 	/* either the tty_lock() or the proc_list_lock() must be held */
4261 
4262 	if (tp->t_pgrp) {
4263 		pg = pg_ref(tp->t_pgrp);
4264 	}
4265 
4266 	return pg;
4267 }
4268 
4269 int
proc_transstart(proc_t p,int locked,int non_blocking)4270 proc_transstart(proc_t p, int locked, int non_blocking)
4271 {
4272 	if (locked == 0) {
4273 		proc_lock(p);
4274 	}
4275 	while ((p->p_lflag & P_LINTRANSIT) == P_LINTRANSIT) {
4276 		if (((p->p_lflag & P_LTRANSCOMMIT) == P_LTRANSCOMMIT) || non_blocking) {
4277 			if (locked == 0) {
4278 				proc_unlock(p);
4279 			}
4280 			return EDEADLK;
4281 		}
4282 		p->p_lflag |= P_LTRANSWAIT;
4283 		msleep(&p->p_lflag, &p->p_mlock, 0, "proc_signstart", NULL);
4284 	}
4285 	p->p_lflag |= P_LINTRANSIT;
4286 	p->p_transholder = current_thread();
4287 	if (locked == 0) {
4288 		proc_unlock(p);
4289 	}
4290 	return 0;
4291 }
4292 
4293 void
proc_transcommit(proc_t p,int locked)4294 proc_transcommit(proc_t p, int locked)
4295 {
4296 	if (locked == 0) {
4297 		proc_lock(p);
4298 	}
4299 
4300 	assert((p->p_lflag & P_LINTRANSIT) == P_LINTRANSIT);
4301 	assert(p->p_transholder == current_thread());
4302 	p->p_lflag |= P_LTRANSCOMMIT;
4303 
4304 	if ((p->p_lflag & P_LTRANSWAIT) == P_LTRANSWAIT) {
4305 		p->p_lflag &= ~P_LTRANSWAIT;
4306 		wakeup(&p->p_lflag);
4307 	}
4308 	if (locked == 0) {
4309 		proc_unlock(p);
4310 	}
4311 }
4312 
4313 void
proc_transend(proc_t p,int locked)4314 proc_transend(proc_t p, int locked)
4315 {
4316 	if (locked == 0) {
4317 		proc_lock(p);
4318 	}
4319 
4320 	p->p_lflag &= ~(P_LINTRANSIT | P_LTRANSCOMMIT);
4321 	p->p_transholder = NULL;
4322 
4323 	if ((p->p_lflag & P_LTRANSWAIT) == P_LTRANSWAIT) {
4324 		p->p_lflag &= ~P_LTRANSWAIT;
4325 		wakeup(&p->p_lflag);
4326 	}
4327 	if (locked == 0) {
4328 		proc_unlock(p);
4329 	}
4330 }
4331 
4332 int
proc_transwait(proc_t p,int locked)4333 proc_transwait(proc_t p, int locked)
4334 {
4335 	if (locked == 0) {
4336 		proc_lock(p);
4337 	}
4338 	while ((p->p_lflag & P_LINTRANSIT) == P_LINTRANSIT) {
4339 		if ((p->p_lflag & P_LTRANSCOMMIT) == P_LTRANSCOMMIT && current_proc() == p) {
4340 			if (locked == 0) {
4341 				proc_unlock(p);
4342 			}
4343 			return EDEADLK;
4344 		}
4345 		p->p_lflag |= P_LTRANSWAIT;
4346 		msleep(&p->p_lflag, &p->p_mlock, 0, "proc_signstart", NULL);
4347 	}
4348 	if (locked == 0) {
4349 		proc_unlock(p);
4350 	}
4351 	return 0;
4352 }
4353 
4354 void
proc_klist_lock(void)4355 proc_klist_lock(void)
4356 {
4357 	lck_mtx_lock(&proc_klist_mlock);
4358 }
4359 
4360 void
proc_klist_unlock(void)4361 proc_klist_unlock(void)
4362 {
4363 	lck_mtx_unlock(&proc_klist_mlock);
4364 }
4365 
4366 void
proc_knote(struct proc * p,long hint)4367 proc_knote(struct proc * p, long hint)
4368 {
4369 	proc_klist_lock();
4370 	KNOTE(&p->p_klist, hint);
4371 	proc_klist_unlock();
4372 }
4373 
4374 void
proc_transfer_knotes(struct proc * old_proc,struct proc * new_proc)4375 proc_transfer_knotes(struct proc *old_proc, struct proc *new_proc)
4376 {
4377 	struct knote *kn = NULL;
4378 
4379 	proc_klist_lock();
4380 	while ((kn = SLIST_FIRST(&old_proc->p_klist))) {
4381 		KNOTE_DETACH(&old_proc->p_klist, kn);
4382 		if (kn->kn_filtid == (uint8_t)~EVFILT_PROC) {
4383 			kn->kn_proc = new_proc;
4384 			KNOTE_ATTACH(&new_proc->p_klist, kn);
4385 		} else {
4386 			assert(kn->kn_filtid == (uint8_t)~EVFILT_SIGNAL);
4387 			kn->kn_proc = NULL;
4388 		}
4389 	}
4390 	proc_klist_unlock();
4391 }
4392 
4393 void
proc_knote_drain(struct proc * p)4394 proc_knote_drain(struct proc *p)
4395 {
4396 	struct knote *kn = NULL;
4397 
4398 	/*
4399 	 * Clear the proc's klist to avoid references after the proc is reaped.
4400 	 */
4401 	proc_klist_lock();
4402 	while ((kn = SLIST_FIRST(&p->p_klist))) {
4403 		kn->kn_proc = PROC_NULL;
4404 		KNOTE_DETACH(&p->p_klist, kn);
4405 	}
4406 	proc_klist_unlock();
4407 }
4408 
4409 void
proc_setregister(proc_t p)4410 proc_setregister(proc_t p)
4411 {
4412 	proc_lock(p);
4413 	p->p_lflag |= P_LREGISTER;
4414 	proc_unlock(p);
4415 }
4416 
4417 void
proc_resetregister(proc_t p)4418 proc_resetregister(proc_t p)
4419 {
4420 	proc_lock(p);
4421 	p->p_lflag &= ~P_LREGISTER;
4422 	proc_unlock(p);
4423 }
4424 
4425 bool
proc_get_pthread_jit_allowlist(proc_t p,bool * late_out)4426 proc_get_pthread_jit_allowlist(proc_t p, bool *late_out)
4427 {
4428 	bool ret = false;
4429 
4430 	proc_lock(p);
4431 	ret = (p->p_lflag & P_LPTHREADJITALLOWLIST);
4432 	*late_out = (p->p_lflag & P_LPTHREADJITFREEZELATE);
4433 	proc_unlock(p);
4434 
4435 	return ret;
4436 }
4437 
4438 void
proc_set_pthread_jit_allowlist(proc_t p,bool late)4439 proc_set_pthread_jit_allowlist(proc_t p, bool late)
4440 {
4441 	proc_lock(p);
4442 	p->p_lflag |= P_LPTHREADJITALLOWLIST;
4443 	if (late) {
4444 		p->p_lflag |= P_LPTHREADJITFREEZELATE;
4445 	}
4446 	proc_unlock(p);
4447 }
4448 
4449 pid_t
proc_pgrpid(proc_t p)4450 proc_pgrpid(proc_t p)
4451 {
4452 	return p->p_pgrpid;
4453 }
4454 
4455 pid_t
proc_sessionid(proc_t p)4456 proc_sessionid(proc_t p)
4457 {
4458 	return p->p_sessionid;
4459 }
4460 
4461 pid_t
proc_selfpgrpid()4462 proc_selfpgrpid()
4463 {
4464 	return current_proc()->p_pgrpid;
4465 }
4466 
4467 
4468 /* return control and action states */
4469 int
proc_getpcontrol(int pid,int * pcontrolp)4470 proc_getpcontrol(int pid, int * pcontrolp)
4471 {
4472 	proc_t p;
4473 
4474 	p = proc_find(pid);
4475 	if (p == PROC_NULL) {
4476 		return ESRCH;
4477 	}
4478 	if (pcontrolp != NULL) {
4479 		*pcontrolp = p->p_pcaction;
4480 	}
4481 
4482 	proc_rele(p);
4483 	return 0;
4484 }
4485 
4486 static int
proc_dopcontrol(proc_t p,memorystatus_kill_cause_t cause)4487 proc_dopcontrol(proc_t p, memorystatus_kill_cause_t cause)
4488 {
4489 	int pcontrol;
4490 	os_reason_t kill_reason;
4491 
4492 	proc_lock(p);
4493 
4494 	pcontrol = PROC_CONTROL_STATE(p);
4495 
4496 	if (PROC_ACTION_STATE(p) == 0) {
4497 		switch (pcontrol) {
4498 		case P_PCTHROTTLE:
4499 			PROC_SETACTION_STATE(p);
4500 			proc_unlock(p);
4501 			memorystatus_log("memorystatus: throttling %s [%d] due to swap exhaustion\n",
4502 			    proc_best_name(p), proc_getpid(p));
4503 			break;
4504 
4505 		case P_PCSUSP:
4506 			PROC_SETACTION_STATE(p);
4507 			proc_unlock(p);
4508 			memorystatus_log("memorystatus: suspending %s [%d] due to swap exhaustion\n",
4509 			    proc_best_name(p), proc_getpid(p));
4510 			task_suspend(proc_task(p));
4511 			break;
4512 
4513 		case P_PCKILL:
4514 			PROC_SETACTION_STATE(p);
4515 			proc_unlock(p);
4516 			memorystatus_log("memorystatus: killing %s [%d] due to swap exhaustion\n",
4517 			    proc_best_name(p), proc_getpid(p));
4518 			kill_reason = os_reason_create(OS_REASON_JETSAM, cause);
4519 			psignal_with_reason(p, SIGKILL, kill_reason);
4520 			break;
4521 
4522 		default:
4523 			memorystatus_log("memorystatus: skipping %s [%d] without pcontrol\n",
4524 			    proc_best_name(p), proc_getpid(p));
4525 			proc_unlock(p);
4526 		}
4527 	} else {
4528 		proc_unlock(p);
4529 	}
4530 
4531 	return PROC_RETURNED;
4532 }
4533 
4534 
4535 /*
4536  * Resume a throttled or suspended process.  This is an internal interface that's only
4537  * used by the user level code that presents the GUI when we run out of swap space and
4538  * hence is restricted to processes with superuser privileges.
4539  */
4540 
4541 int
proc_resetpcontrol(int pid)4542 proc_resetpcontrol(int pid)
4543 {
4544 	proc_t p;
4545 	int pcontrol;
4546 	int error;
4547 	proc_t self = current_proc();
4548 
4549 	/* if the process has been validated to handle resource control or root is valid one */
4550 	if (((self->p_lflag & P_LVMRSRCOWNER) == 0) && (error = suser(kauth_cred_get(), 0))) {
4551 		return error;
4552 	}
4553 
4554 	p = proc_find(pid);
4555 	if (p == PROC_NULL) {
4556 		return ESRCH;
4557 	}
4558 
4559 	proc_lock(p);
4560 
4561 	pcontrol = PROC_CONTROL_STATE(p);
4562 
4563 	if (PROC_ACTION_STATE(p) != 0) {
4564 		switch (pcontrol) {
4565 		case P_PCTHROTTLE:
4566 			PROC_RESETACTION_STATE(p);
4567 			proc_unlock(p);
4568 			memorystatus_log("memorystatus: unthrottling %s [%d]\n",
4569 			    proc_best_name(p), proc_getpid(p));
4570 			break;
4571 
4572 		case P_PCSUSP:
4573 			PROC_RESETACTION_STATE(p);
4574 			proc_unlock(p);
4575 			memorystatus_log("memorystatus: resuming %s [%d]\n",
4576 			    proc_best_name(p), proc_getpid(p));
4577 			task_resume(proc_task(p));
4578 			break;
4579 
4580 		case P_PCKILL:
4581 			/* Huh? */
4582 			PROC_SETACTION_STATE(p);
4583 			proc_unlock(p);
4584 			memorystatus_log_error("memorystatus: attempt to unkill pid %s [%d] ignored\n",
4585 			    proc_best_name(p), proc_getpid(p));
4586 			break;
4587 
4588 		default:
4589 			proc_unlock(p);
4590 		}
4591 	} else {
4592 		proc_unlock(p);
4593 	}
4594 
4595 	proc_rele(p);
4596 	return 0;
4597 }
4598 
4599 struct no_paging_space {
4600 	uint64_t        pcs_max_size;
4601 	uint64_t        pcs_uniqueid;
4602 	int             pcs_pid;
4603 	int             pcs_proc_count;
4604 	uint64_t        pcs_total_size;
4605 
4606 	uint64_t        npcs_max_size;
4607 	uint64_t        npcs_uniqueid;
4608 	int             npcs_pid;
4609 	int             npcs_proc_count;
4610 	uint64_t        npcs_total_size;
4611 
4612 	int             apcs_proc_count;
4613 	uint64_t        apcs_total_size;
4614 };
4615 
4616 static int
proc_pcontrol_filter(proc_t p,void * arg)4617 proc_pcontrol_filter(proc_t p, void *arg)
4618 {
4619 	struct no_paging_space *nps;
4620 	uint64_t        compressed;
4621 
4622 	nps = (struct no_paging_space *)arg;
4623 
4624 	compressed = get_task_compressed(proc_task(p));
4625 
4626 	if (PROC_CONTROL_STATE(p)) {
4627 		if (PROC_ACTION_STATE(p) == 0) {
4628 			if (compressed > nps->pcs_max_size) {
4629 				nps->pcs_pid = proc_getpid(p);
4630 				nps->pcs_uniqueid = proc_uniqueid(p);
4631 				nps->pcs_max_size = compressed;
4632 			}
4633 			nps->pcs_total_size += compressed;
4634 			nps->pcs_proc_count++;
4635 		} else {
4636 			nps->apcs_total_size += compressed;
4637 			nps->apcs_proc_count++;
4638 		}
4639 	} else {
4640 		if (compressed > nps->npcs_max_size) {
4641 			nps->npcs_pid = proc_getpid(p);
4642 			nps->npcs_uniqueid = proc_uniqueid(p);
4643 			nps->npcs_max_size = compressed;
4644 		}
4645 		nps->npcs_total_size += compressed;
4646 		nps->npcs_proc_count++;
4647 	}
4648 	return 0;
4649 }
4650 
4651 
4652 static int
proc_pcontrol_null(__unused proc_t p,__unused void * arg)4653 proc_pcontrol_null(__unused proc_t p, __unused void *arg)
4654 {
4655 	return PROC_RETURNED;
4656 }
4657 
4658 /*
4659  * Deal with the low on compressor pool space condition... this function
4660  * gets called when we are approaching the limits of the compressor pool or
4661  * we are unable to create a new swap file.
4662  * Since this eventually creates a memory deadlock situtation, we need to take action to free up
4663  * memory resources (both compressed and uncompressed) in order to prevent the system from hanging completely.
4664  * There are 2 categories of processes to deal with.  Those that have an action
4665  * associated with them by the task itself and those that do not.  Actionable
4666  * tasks can have one of three categories specified:  ones that
4667  * can be killed immediately, ones that should be suspended, and ones that should
4668  * be throttled.  Processes that do not have an action associated with them are normally
4669  * ignored unless they are utilizing such a large percentage of the compressor pool (currently 50%)
4670  * that only by killing them can we hope to put the system back into a usable state.
4671  */
4672 
4673 #define MB_SIZE (1024 * 1024ULL)
4674 
4675 extern int32_t  max_kill_priority;
4676 
4677 bool
no_paging_space_action(void)4678 no_paging_space_action(void)
4679 {
4680 	proc_t          p;
4681 	struct no_paging_space nps;
4682 	os_reason_t kill_reason;
4683 
4684 	memorystatus_log("memorystatus: triggering no paging space action\n");
4685 
4686 	/*
4687 	 * Examine all processes and find the biggest (biggest is based on the number of pages this
4688 	 * task has in the compressor pool) that has been marked to have some action
4689 	 * taken when swap space runs out... we also find the biggest that hasn't been marked for
4690 	 * action.
4691 	 *
4692 	 * If the biggest non-actionable task is over the "dangerously big" threashold (currently 50% of
4693 	 * the total number of pages held by the compressor, we go ahead and kill it since no other task
4694 	 * can have any real effect on the situation.  Otherwise, we go after the actionable process.
4695 	 */
4696 	bzero(&nps, sizeof(nps));
4697 
4698 	proc_iterate(PROC_ALLPROCLIST, proc_pcontrol_null, (void *)NULL, proc_pcontrol_filter, (void *)&nps);
4699 
4700 	memorystatus_log_debug("memorystatus: npcs_proc_count = %d, npcs_total_size = %qd, npcs_max_size = %qd\n",
4701 	    nps.npcs_proc_count, nps.npcs_total_size, nps.npcs_max_size);
4702 	memorystatus_log_debug("memorystatus: pcs_proc_count = %d, pcs_total_size = %qd, pcs_max_size = %qd\n",
4703 	    nps.pcs_proc_count, nps.pcs_total_size, nps.pcs_max_size);
4704 	memorystatus_log_debug("memorystatus: apcs_proc_count = %d, apcs_total_size = %qd\n",
4705 	    nps.apcs_proc_count, nps.apcs_total_size);
4706 	if (nps.npcs_max_size > (vm_compressor_pages_compressed() * PAGE_SIZE_64 * 50ull) / 100ull) {
4707 		/*
4708 		 * for now we'll knock out any task that has more then 50% of the pages
4709 		 * held by the compressor
4710 		 */
4711 		if ((p = proc_find(nps.npcs_pid)) != PROC_NULL) {
4712 			if (nps.npcs_uniqueid == proc_uniqueid(p)) {
4713 				/*
4714 				 * verify this is still the same process
4715 				 * in case the proc exited and the pid got reused while
4716 				 * we were finishing the proc_iterate and getting to this point
4717 				 */
4718 				memorystatus_log("memorystatus: killing largest compressed process %s [%d] "
4719 				    "%llu MB\n",
4720 				    proc_best_name(p), proc_getpid(p), (nps.npcs_max_size / MB_SIZE));
4721 				kill_reason = os_reason_create(OS_REASON_JETSAM, JETSAM_REASON_LOWSWAP);
4722 				psignal_with_reason(p, SIGKILL, kill_reason);
4723 
4724 				proc_rele(p);
4725 
4726 				return false;
4727 			}
4728 
4729 			proc_rele(p);
4730 		}
4731 	}
4732 
4733 	if (memstat_get_idle_proccnt() > 0) {
4734 		/*
4735 		 * There are still idle processes to kill.
4736 		 */
4737 		return false;
4738 	}
4739 
4740 	if (nps.pcs_max_size > 0) {
4741 		memorystatus_log("memorystatus: attempting pcontrol on "
4742 		    "[%d]\n", nps.pcs_pid);
4743 		if ((p = proc_find(nps.pcs_pid)) != PROC_NULL) {
4744 			if (nps.pcs_uniqueid == proc_uniqueid(p)) {
4745 				/*
4746 				 * verify this is still the same process
4747 				 * in case the proc exited and the pid got reused while
4748 				 * we were finishing the proc_iterate and getting to this point
4749 				 */
4750 				memorystatus_log("memorystatus: doing "
4751 				    "pcontrol on %s [%d]\n",
4752 				    proc_best_name(p), proc_getpid(p));
4753 				proc_dopcontrol(p, JETSAM_REASON_LOWSWAP);
4754 
4755 				proc_rele(p);
4756 
4757 				return true;
4758 			} else {
4759 				memorystatus_log("memorystatus: cannot "
4760 				    "find process for [%d] -- may have exited\n",
4761 				    nps.pcs_pid);
4762 			}
4763 
4764 			proc_rele(p);
4765 		}
4766 	}
4767 
4768 	memorystatus_log("memorystatus: unable to find any eligible processes to take action on\n");
4769 	return false;
4770 }
4771 
4772 int
proc_trace_log(__unused proc_t p,struct proc_trace_log_args * uap,__unused int * retval)4773 proc_trace_log(__unused proc_t p, struct proc_trace_log_args *uap, __unused int *retval)
4774 {
4775 	int ret = 0;
4776 	proc_t target_proc = PROC_NULL;
4777 	pid_t target_pid = uap->pid;
4778 	uint64_t target_uniqueid = uap->uniqueid;
4779 	task_t target_task = NULL;
4780 
4781 	if (priv_check_cred(kauth_cred_get(), PRIV_PROC_TRACE_INSPECT, 0)) {
4782 		ret = EPERM;
4783 		goto out;
4784 	}
4785 	target_proc = proc_find(target_pid);
4786 	if (target_proc != PROC_NULL) {
4787 		if (target_uniqueid != proc_uniqueid(target_proc)) {
4788 			ret = ENOENT;
4789 			goto out;
4790 		}
4791 
4792 		target_task = proc_task(target_proc);
4793 		if (task_send_trace_memory(target_task, target_pid, target_uniqueid)) {
4794 			ret = EINVAL;
4795 			goto out;
4796 		}
4797 	} else {
4798 		ret = ENOENT;
4799 	}
4800 
4801 out:
4802 	if (target_proc != PROC_NULL) {
4803 		proc_rele(target_proc);
4804 	}
4805 	return ret;
4806 }
4807 
4808 #if VM_SCAN_FOR_SHADOW_CHAIN
4809 int proc_shadow_max(void);
4810 int
proc_shadow_max(void)4811 proc_shadow_max(void)
4812 {
4813 	int             retval, max;
4814 	proc_t          p;
4815 	task_t          task;
4816 	vm_map_t        map;
4817 
4818 	max = 0;
4819 	proc_list_lock();
4820 	for (p = allproc.lh_first; (p != 0); p = p->p_list.le_next) {
4821 		if (p->p_stat == SIDL) {
4822 			continue;
4823 		}
4824 		task = proc_task(p);
4825 		if (task == NULL) {
4826 			continue;
4827 		}
4828 		map = get_task_map(task);
4829 		if (map == NULL) {
4830 			continue;
4831 		}
4832 		retval = vm_map_shadow_max(map);
4833 		if (retval > max) {
4834 			max = retval;
4835 		}
4836 	}
4837 	proc_list_unlock();
4838 	return max;
4839 }
4840 #endif /* VM_SCAN_FOR_SHADOW_CHAIN */
4841 
4842 void proc_set_responsible_pid(proc_t target_proc, pid_t responsible_pid);
4843 void
proc_set_responsible_pid(proc_t target_proc,pid_t responsible_pid)4844 proc_set_responsible_pid(proc_t target_proc, pid_t responsible_pid)
4845 {
4846 	if (target_proc != NULL) {
4847 		target_proc->p_responsible_pid = responsible_pid;
4848 
4849 		// Also save the responsible UUID
4850 		if (responsible_pid >= 0) {
4851 			proc_t responsible_proc = proc_find(responsible_pid);
4852 			if (responsible_proc != PROC_NULL) {
4853 				proc_getexecutableuuid(responsible_proc, target_proc->p_responsible_uuid, sizeof(target_proc->p_responsible_uuid));
4854 				proc_rele(responsible_proc);
4855 			}
4856 		}
4857 	}
4858 	return;
4859 }
4860 
4861 int
proc_chrooted(proc_t p)4862 proc_chrooted(proc_t p)
4863 {
4864 	int retval = 0;
4865 
4866 	if (p) {
4867 		proc_fdlock(p);
4868 		retval = (p->p_fd.fd_rdir != NULL) ? 1 : 0;
4869 		proc_fdunlock(p);
4870 	}
4871 
4872 	return retval;
4873 }
4874 
4875 boolean_t
proc_send_synchronous_EXC_RESOURCE(proc_t p)4876 proc_send_synchronous_EXC_RESOURCE(proc_t p)
4877 {
4878 	if (p == PROC_NULL) {
4879 		return FALSE;
4880 	}
4881 
4882 	/* Send sync EXC_RESOURCE if the process is traced */
4883 	if (ISSET(p->p_lflag, P_LTRACED)) {
4884 		return TRUE;
4885 	}
4886 	return FALSE;
4887 }
4888 
4889 #if CONFIG_MACF
4890 size_t
proc_get_syscall_filter_mask_size(int which)4891 proc_get_syscall_filter_mask_size(int which)
4892 {
4893 	switch (which) {
4894 	case SYSCALL_MASK_UNIX:
4895 		return nsysent;
4896 	case SYSCALL_MASK_MACH:
4897 		return mach_trap_count;
4898 	case SYSCALL_MASK_KOBJ:
4899 		return mach_kobj_count;
4900 	default:
4901 		return 0;
4902 	}
4903 }
4904 
4905 unsigned char *
proc_get_syscall_filter_mask(proc_t p,int which)4906 proc_get_syscall_filter_mask(proc_t p, int which)
4907 {
4908 	switch (which) {
4909 	case SYSCALL_MASK_UNIX:
4910 		return proc_syscall_filter_mask(p);
4911 	case SYSCALL_MASK_MACH:
4912 		return mac_task_get_mach_filter_mask(proc_task(p));
4913 	case SYSCALL_MASK_KOBJ:
4914 		return mac_task_get_kobj_filter_mask(proc_task(p));
4915 	default:
4916 		return NULL;
4917 	}
4918 }
4919 
4920 int
proc_set_syscall_filter_mask(proc_t p,int which,unsigned char * maskptr,size_t masklen)4921 proc_set_syscall_filter_mask(proc_t p, int which, unsigned char *maskptr, size_t masklen)
4922 {
4923 #if DEVELOPMENT || DEBUG
4924 	if (syscallfilter_disable) {
4925 		printf("proc_set_syscall_filter_mask: attempt to set policy for pid %d, but disabled by boot-arg\n", proc_pid(p));
4926 		return 0;
4927 	}
4928 #endif // DEVELOPMENT || DEBUG
4929 
4930 	switch (which) {
4931 	case SYSCALL_MASK_UNIX:
4932 		if (maskptr != NULL && masklen != nsysent) {
4933 			return EINVAL;
4934 		}
4935 		proc_syscall_filter_mask_set(p, maskptr);
4936 		break;
4937 	case SYSCALL_MASK_MACH:
4938 		if (maskptr != NULL && masklen != (size_t)mach_trap_count) {
4939 			return EINVAL;
4940 		}
4941 		mac_task_set_mach_filter_mask(proc_task(p), maskptr);
4942 		break;
4943 	case SYSCALL_MASK_KOBJ:
4944 		if (maskptr != NULL && masklen != (size_t)mach_kobj_count) {
4945 			return EINVAL;
4946 		}
4947 		mac_task_set_kobj_filter_mask(proc_task(p), maskptr);
4948 		break;
4949 	default:
4950 		return EINVAL;
4951 	}
4952 
4953 	return 0;
4954 }
4955 
4956 int
proc_set_syscall_filter_callbacks(syscall_filter_cbs_t cbs)4957 proc_set_syscall_filter_callbacks(syscall_filter_cbs_t cbs)
4958 {
4959 	if (cbs->version != SYSCALL_FILTER_CALLBACK_VERSION) {
4960 		return EINVAL;
4961 	}
4962 
4963 	/* XXX register unix filter callback instead of using MACF hook. */
4964 
4965 	if (cbs->mach_filter_cbfunc || cbs->kobj_filter_cbfunc) {
4966 		if (mac_task_register_filter_callbacks(cbs->mach_filter_cbfunc,
4967 		    cbs->kobj_filter_cbfunc) != 0) {
4968 			return EPERM;
4969 		}
4970 	}
4971 
4972 	return 0;
4973 }
4974 
4975 int
proc_set_syscall_filter_index(int which,int num,int index)4976 proc_set_syscall_filter_index(int which, int num, int index)
4977 {
4978 	switch (which) {
4979 	case SYSCALL_MASK_KOBJ:
4980 		if (ipc_kobject_set_kobjidx(num, index) != 0) {
4981 			return ENOENT;
4982 		}
4983 		break;
4984 	default:
4985 		return EINVAL;
4986 	}
4987 
4988 	return 0;
4989 }
4990 #endif /* CONFIG_MACF */
4991 
4992 int
proc_set_filter_message_flag(proc_t p,boolean_t flag)4993 proc_set_filter_message_flag(proc_t p, boolean_t flag)
4994 {
4995 	if (p == PROC_NULL) {
4996 		return EINVAL;
4997 	}
4998 
4999 	task_set_filter_msg_flag(proc_task(p), flag);
5000 
5001 	return 0;
5002 }
5003 
5004 int
proc_get_filter_message_flag(proc_t p,boolean_t * flag)5005 proc_get_filter_message_flag(proc_t p, boolean_t *flag)
5006 {
5007 	if (p == PROC_NULL || flag == NULL) {
5008 		return EINVAL;
5009 	}
5010 
5011 	*flag = task_get_filter_msg_flag(proc_task(p));
5012 
5013 	return 0;
5014 }
5015 
5016 bool
proc_is_traced(proc_t p)5017 proc_is_traced(proc_t p)
5018 {
5019 	bool ret = FALSE;
5020 	assert(p != PROC_NULL);
5021 	proc_lock(p);
5022 	if (p->p_lflag & P_LTRACED) {
5023 		ret = TRUE;
5024 	}
5025 	proc_unlock(p);
5026 	return ret;
5027 }
5028 
5029 #if CONFIG_PROC_RESOURCE_LIMITS
5030 int
proc_set_filedesc_limits(proc_t p,int soft_limit,int hard_limit)5031 proc_set_filedesc_limits(proc_t p, int soft_limit, int hard_limit)
5032 {
5033 	struct filedesc *fdp = &p->p_fd;
5034 	int retval = 0;
5035 
5036 	proc_fdlock(p);
5037 
5038 	if (hard_limit > 0) {
5039 		if (soft_limit >= hard_limit) {
5040 			soft_limit = 0;
5041 		}
5042 	}
5043 	fdp->fd_nfiles_soft_limit = soft_limit;
5044 	fdp->fd_nfiles_hard_limit = hard_limit;
5045 	/* Make sure that current fd_nfiles hasn't already exceeded these limits */
5046 	fd_check_limit_exceeded(fdp);
5047 
5048 	proc_fdunlock(p);
5049 
5050 	return retval;
5051 }
5052 
5053 int
proc_set_kqworkloop_limits(proc_t p,int soft_limit,int hard_limit)5054 proc_set_kqworkloop_limits(proc_t p, int soft_limit, int hard_limit)
5055 {
5056 	struct filedesc *fdp = &p->p_fd;
5057 	lck_mtx_lock_spin_always(&fdp->fd_kqhashlock);
5058 
5059 	fdp->kqwl_dyn_soft_limit = soft_limit;
5060 	fdp->kqwl_dyn_hard_limit = hard_limit;
5061 	/* Make sure existing limits aren't exceeded already */
5062 	kqworkloop_check_limit_exceeded(fdp);
5063 
5064 	lck_mtx_unlock(&fdp->fd_kqhashlock);
5065 	return 0;
5066 }
5067 
5068 static int
proc_evaluate_fd_limits_ast(proc_t p,struct filedesc * fdp,int * soft_limit,int * hard_limit)5069 proc_evaluate_fd_limits_ast(proc_t p, struct filedesc *fdp, int *soft_limit, int *hard_limit)
5070 {
5071 	int fd_current_size, fd_soft_limit, fd_hard_limit;
5072 	proc_fdlock(p);
5073 
5074 	fd_current_size = fdp->fd_nfiles_open;
5075 	fd_hard_limit = fdp->fd_nfiles_hard_limit;
5076 	fd_soft_limit = fdp->fd_nfiles_soft_limit;
5077 
5078 	/*
5079 	 * If a thread is going to take action on a specific limit exceeding, it also
5080 	 * clears it out to a SENTINEL so that future threads don't reevaluate the
5081 	 * limit as having exceeded again
5082 	 */
5083 	if (fd_hard_limit > 0 && fd_current_size >= fd_hard_limit) {
5084 		/* Clear our soft limit when we are sending hard limit notification */
5085 		fd_soft_limit = 0;
5086 
5087 		fdp->fd_nfiles_hard_limit = FD_LIMIT_SENTINEL;
5088 	} else if (fd_soft_limit > 0 && fd_current_size >= fd_soft_limit) {
5089 		/* Clear out hard limit when we are sending soft limit notification */
5090 		fd_hard_limit = 0;
5091 
5092 		fdp->fd_nfiles_soft_limit = FD_LIMIT_SENTINEL;
5093 	} else {
5094 		/* Neither limits were exceeded */
5095 		fd_soft_limit = fd_hard_limit = 0;
5096 	}
5097 
5098 	proc_fdunlock(p);
5099 
5100 	*soft_limit = fd_soft_limit;
5101 	*hard_limit = fd_hard_limit;
5102 	return fd_current_size;
5103 }
5104 
5105 static int
proc_evaluate_kqwl_limits_ast(struct filedesc * fdp,int * soft_limit,int * hard_limit)5106 proc_evaluate_kqwl_limits_ast(struct filedesc *fdp, int *soft_limit, int *hard_limit)
5107 {
5108 	lck_mtx_lock_spin_always(&fdp->fd_kqhashlock);
5109 
5110 	int kqwl_current_size = fdp->num_kqwls;
5111 	int kqwl_soft_limit = fdp->kqwl_dyn_soft_limit;
5112 	int kqwl_hard_limit = fdp->kqwl_dyn_hard_limit;
5113 
5114 	/*
5115 	 * If a thread is going to take action on a specific limit exceeding, it also
5116 	 * clears it out to a SENTINEL so that future threads don't reevaluate the
5117 	 * limit as having exceeded again
5118 	 */
5119 	if (kqwl_hard_limit > 0 && kqwl_current_size >= kqwl_hard_limit) {
5120 		/* Clear our soft limit when we are sending hard limit notification */
5121 		kqwl_soft_limit = 0;
5122 
5123 		fdp->kqwl_dyn_hard_limit = KQWL_LIMIT_SENTINEL;
5124 	} else if (kqwl_soft_limit > 0 && kqwl_current_size >= kqwl_soft_limit) {
5125 		/* Clear out hard limit when we are sending soft limit notification */
5126 		kqwl_hard_limit = 0;
5127 
5128 		fdp->kqwl_dyn_soft_limit = KQWL_LIMIT_SENTINEL;
5129 	} else {
5130 		/* Neither limits were exceeded */
5131 		kqwl_soft_limit = kqwl_hard_limit = 0;
5132 	}
5133 
5134 	lck_mtx_unlock(&fdp->fd_kqhashlock);
5135 
5136 	*soft_limit = kqwl_soft_limit;
5137 	*hard_limit = kqwl_hard_limit;
5138 	return kqwl_current_size;
5139 }
5140 #endif /* CONFIG_PROC_RESOURCE_LIMITS */
5141 
5142 void
proc_filedesc_ast(__unused task_t task)5143 proc_filedesc_ast(__unused task_t task)
5144 {
5145 #if CONFIG_PROC_RESOURCE_LIMITS
5146 	assert(task == current_task());
5147 	proc_t p = get_bsdtask_info(task);
5148 	struct filedesc *fdp = &p->p_fd;
5149 
5150 	/*
5151 	 * At this point, we can possibly race with other threads which set the AST
5152 	 * due to triggering the soft/hard limits for fd or kqworkloops.
5153 	 *
5154 	 * The first thread to reach this logic will always evaluate hard limit for fd
5155 	 * or kqworkloops even if it was the one which triggered the soft limit for
5156 	 * them.
5157 	 *
5158 	 * If a thread takes action on a specific limit, it will clear the limit value
5159 	 * in the fdp with a SENTINEL to indicate to other racing threads that they no
5160 	 * longer need to evaluate it.
5161 	 */
5162 	int soft_limit, hard_limit;
5163 	int fd_current_size = proc_evaluate_fd_limits_ast(p, fdp, &soft_limit, &hard_limit);
5164 
5165 	if (hard_limit || soft_limit) {
5166 		return task_filedesc_ast(task, fd_current_size, soft_limit, hard_limit);
5167 	}
5168 
5169 	int kqwl_current_size = proc_evaluate_kqwl_limits_ast(fdp, &soft_limit, &hard_limit);
5170 	if (hard_limit || soft_limit) {
5171 		return task_kqworkloop_ast(task, kqwl_current_size, soft_limit, hard_limit);
5172 	}
5173 #endif /* CONFIG_PROC_RESOURCE_LIMITS */
5174 }
5175 
5176 proc_ro_t
proc_ro_alloc(proc_t p,proc_ro_data_t p_data,task_t t,task_ro_data_t t_data)5177 proc_ro_alloc(proc_t p, proc_ro_data_t p_data, task_t t, task_ro_data_t t_data)
5178 {
5179 	proc_ro_t pr;
5180 	struct proc_ro pr_local = {};
5181 
5182 	pr = (proc_ro_t)zalloc_ro(ZONE_ID_PROC_RO, Z_WAITOK | Z_NOFAIL | Z_ZERO);
5183 
5184 	if (p != PROC_NULL) {
5185 		pr_local.pr_proc = p;
5186 		pr_local.proc_data = *p_data;
5187 	}
5188 
5189 	if (t != TASK_NULL) {
5190 		pr_local.pr_task = t;
5191 		pr_local.task_data = *t_data;
5192 	}
5193 
5194 	if ((p != PROC_NULL) || (t != TASK_NULL)) {
5195 		zalloc_ro_update_elem(ZONE_ID_PROC_RO, pr, &pr_local);
5196 	}
5197 
5198 	return pr;
5199 }
5200 
5201 proc_ro_t
proc_ro_ref_task(proc_ro_t pr,task_t t,task_ro_data_t t_data)5202 proc_ro_ref_task(proc_ro_t pr, task_t t, task_ro_data_t t_data)
5203 {
5204 	struct proc_ro pr_local;
5205 
5206 	if (pr->pr_task != TASK_NULL) {
5207 		panic("%s: proc_ro already has an owning task", __func__);
5208 	}
5209 
5210 	pr_local = *pr;
5211 	pr_local.pr_task = t;
5212 	pr_local.task_data = *t_data;
5213 
5214 	zalloc_ro_update_elem(ZONE_ID_PROC_RO, pr, &pr_local);
5215 
5216 	return pr;
5217 }
5218 
5219 void
proc_ro_erase_task(proc_ro_t pr)5220 proc_ro_erase_task(proc_ro_t pr)
5221 {
5222 	zalloc_ro_update_field_atomic(ZONE_ID_PROC_RO,
5223 	    pr, pr_task, ZRO_ATOMIC_XCHG_LONG, TASK_NULL);
5224 }
5225 
5226 __abortlike
5227 static void
panic_proc_ro_proc_backref_mismatch(proc_t p,proc_ro_t ro)5228 panic_proc_ro_proc_backref_mismatch(proc_t p, proc_ro_t ro)
5229 {
5230 	panic("proc_ro->proc backref mismatch: p=%p, ro=%p, "
5231 	    "ro->pr_proc(ro)=%p", p, ro, ro->pr_proc);
5232 }
5233 
5234 proc_ro_t
proc_get_ro(proc_t p)5235 proc_get_ro(proc_t p)
5236 {
5237 	proc_ro_t ro = p->p_proc_ro;
5238 
5239 	zone_require_ro(ZONE_ID_PROC_RO, sizeof(struct proc_ro), ro);
5240 	if (__improbable(ro->pr_proc != p)) {
5241 		panic_proc_ro_proc_backref_mismatch(p, ro);
5242 	}
5243 
5244 	return ro;
5245 }
5246 
5247 task_t
proc_ro_task(proc_ro_t pr)5248 proc_ro_task(proc_ro_t pr)
5249 {
5250 	return pr->pr_task;
5251 }
5252 
5253 /*
5254  * pid_for_task
5255  *
5256  * Find the BSD process ID for the Mach task associated with the given Mach port
5257  * name
5258  *
5259  * Parameters:	args		User argument descriptor (see below)
5260  *
5261  * Indirect parameters:	args->t		Mach port name
5262  *                      args->pid	Process ID (returned value; see below)
5263  *
5264  * Returns:	KERL_SUCCESS	Success
5265  *              KERN_FAILURE	Not success
5266  *
5267  * Implicit returns: args->pid		Process ID
5268  *
5269  */
5270 kern_return_t
pid_for_task(struct pid_for_task_args * args)5271 pid_for_task(
5272 	struct pid_for_task_args *args)
5273 {
5274 	mach_port_name_t        t = args->t;
5275 	user_addr_t             pid_addr  = args->pid;
5276 	proc_t p;
5277 	task_t          t1;
5278 	int     pid = -1;
5279 	kern_return_t   err = KERN_SUCCESS;
5280 
5281 	AUDIT_MACH_SYSCALL_ENTER(AUE_PIDFORTASK);
5282 	AUDIT_ARG(mach_port1, t);
5283 
5284 	t1 = port_name_to_task_name(t);
5285 
5286 	if (t1 == TASK_NULL) {
5287 		err = KERN_FAILURE;
5288 		goto pftout;
5289 	} else {
5290 		p = get_bsdtask_info(t1);
5291 		if (p) {
5292 			pid  = proc_pid(p);
5293 			err = KERN_SUCCESS;
5294 		} else if (task_is_a_corpse(t1)) {
5295 			pid = task_pid(t1);
5296 			err = KERN_SUCCESS;
5297 		} else {
5298 			err = KERN_FAILURE;
5299 		}
5300 	}
5301 	task_deallocate(t1);
5302 pftout:
5303 	AUDIT_ARG(pid, pid);
5304 	(void) copyout((char *) &pid, pid_addr, sizeof(int));
5305 	AUDIT_MACH_SYSCALL_EXIT(err);
5306 	return err;
5307 }
5308 
5309 /*
5310  *
5311  * tfp_policy = KERN_TFP_POLICY_DENY; Deny Mode: None allowed except for self
5312  * tfp_policy = KERN_TFP_POLICY_DEFAULT; default mode: all posix checks and upcall via task port for authentication
5313  *
5314  */
5315 static  int tfp_policy = KERN_TFP_POLICY_DEFAULT;
5316 
5317 static int
sysctl_settfp_policy(__unused struct sysctl_oid * oidp,void * arg1,__unused int arg2,struct sysctl_req * req)5318 sysctl_settfp_policy(__unused struct sysctl_oid *oidp, void *arg1,
5319     __unused int arg2, struct sysctl_req *req)
5320 {
5321 	int error = 0;
5322 	int new_value;
5323 
5324 	error = SYSCTL_OUT(req, arg1, sizeof(int));
5325 	if (error || req->newptr == USER_ADDR_NULL) {
5326 		return error;
5327 	}
5328 
5329 	if (!kauth_cred_issuser(kauth_cred_get())) {
5330 		return EPERM;
5331 	}
5332 
5333 	if ((error = SYSCTL_IN(req, &new_value, sizeof(int)))) {
5334 		goto out;
5335 	}
5336 	if ((new_value == KERN_TFP_POLICY_DENY)
5337 	    || (new_value == KERN_TFP_POLICY_DEFAULT)) {
5338 		tfp_policy = new_value;
5339 	} else {
5340 		error = EINVAL;
5341 	}
5342 out:
5343 	return error;
5344 }
5345 
5346 SYSCTL_NODE(_kern, KERN_TFP, tfp, CTLFLAG_RW | CTLFLAG_LOCKED, 0, "tfp");
5347 SYSCTL_PROC(_kern_tfp, KERN_TFP_POLICY, policy, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
5348     &tfp_policy, sizeof(uint32_t), &sysctl_settfp_policy, "I", "policy");
5349 
5350 /*
5351  *	Routine:	task_for_pid_posix_check
5352  *	Purpose:
5353  *			Verify that the current process should be allowed to
5354  *			get the target process's task port. This is only
5355  *			permitted if:
5356  *			- The current process is root
5357  *			OR all of the following are true:
5358  *			- The target process's real, effective, and saved uids
5359  *			  are the same as the current proc's euid,
5360  *			- The target process's group set is a subset of the
5361  *			  calling process's group set, and
5362  *			- The target process hasn't switched credentials.
5363  *
5364  *	Returns:	TRUE: permitted
5365  *			FALSE: denied
5366  */
5367 static int
task_for_pid_posix_check(proc_t target)5368 task_for_pid_posix_check(proc_t target)
5369 {
5370 	kauth_cred_t targetcred, mycred;
5371 	bool checkcredentials;
5372 	uid_t myuid;
5373 	int allowed;
5374 
5375 	/* No task_for_pid on bad targets */
5376 	if (target->p_stat == SZOMB) {
5377 		return FALSE;
5378 	}
5379 
5380 	mycred = kauth_cred_get();
5381 	myuid = kauth_cred_getuid(mycred);
5382 
5383 	/* If we're running as root, the check passes */
5384 	if (kauth_cred_issuser(mycred)) {
5385 		return TRUE;
5386 	}
5387 
5388 	/* We're allowed to get our own task port */
5389 	if (target == current_proc()) {
5390 		return TRUE;
5391 	}
5392 
5393 	/*
5394 	 * Under DENY, only root can get another proc's task port,
5395 	 * so no more checks are needed.
5396 	 */
5397 	if (tfp_policy == KERN_TFP_POLICY_DENY) {
5398 		return FALSE;
5399 	}
5400 
5401 	targetcred = kauth_cred_proc_ref(target);
5402 	allowed = TRUE;
5403 
5404 	checkcredentials = !proc_is_third_party_debuggable_driver(target);
5405 
5406 	if (checkcredentials) {
5407 		/* Do target's ruid, euid, and saved uid match my euid? */
5408 		if ((kauth_cred_getuid(targetcred) != myuid) ||
5409 		    (kauth_cred_getruid(targetcred) != myuid) ||
5410 		    (kauth_cred_getsvuid(targetcred) != myuid)) {
5411 			allowed = FALSE;
5412 			goto out;
5413 		}
5414 		/* Are target's groups a subset of my groups? */
5415 		if (kauth_cred_gid_subset(targetcred, mycred, &allowed) ||
5416 		    allowed == 0) {
5417 			allowed = FALSE;
5418 			goto out;
5419 		}
5420 	}
5421 
5422 	/* Has target switched credentials? */
5423 	if (target->p_flag & P_SUGID) {
5424 		allowed = FALSE;
5425 		goto out;
5426 	}
5427 
5428 out:
5429 	kauth_cred_unref(&targetcred);
5430 	return allowed;
5431 }
5432 
5433 /*
5434  *	__KERNEL_WAITING_ON_TASKGATED_CHECK_ACCESS_UPCALL__
5435  *
5436  *	Description:	Waits for the user space daemon to respond to the request
5437  *			we made. Function declared non inline to be visible in
5438  *			stackshots and spindumps as well as debugging.
5439  */
5440 static __attribute__((noinline)) int
__KERNEL_WAITING_ON_TASKGATED_CHECK_ACCESS_UPCALL__(mach_port_t task_access_port,int32_t calling_pid,uint32_t calling_gid,int32_t target_pid,mach_task_flavor_t flavor)5441 __KERNEL_WAITING_ON_TASKGATED_CHECK_ACCESS_UPCALL__(
5442 	mach_port_t task_access_port, int32_t calling_pid, uint32_t calling_gid, int32_t target_pid, mach_task_flavor_t flavor)
5443 {
5444 	return check_task_access_with_flavor(task_access_port, calling_pid, calling_gid, target_pid, flavor);
5445 }
5446 
5447 /*
5448  *	Routine:	task_for_pid
5449  *	Purpose:
5450  *		Get the task port for another "process", named by its
5451  *		process ID on the same host as "target_task".
5452  *
5453  *		Only permitted to privileged processes, or processes
5454  *		with the same user ID.
5455  *
5456  *		Note: if pid == 0, an error is return no matter who is calling.
5457  *
5458  * XXX This should be a BSD system call, not a Mach trap!!!
5459  */
5460 kern_return_t
task_for_pid(struct task_for_pid_args * args)5461 task_for_pid(
5462 	struct task_for_pid_args *args)
5463 {
5464 	mach_port_name_t        target_tport = args->target_tport;
5465 	int                     pid = args->pid;
5466 	user_addr_t             task_addr = args->t;
5467 	proc_t                  p = PROC_NULL;
5468 	task_t                  t1 = TASK_NULL;
5469 	task_t                  task = TASK_NULL;
5470 	mach_port_name_t        tret = MACH_PORT_NULL;
5471 	ipc_port_t              tfpport = MACH_PORT_NULL;
5472 	void                    * sright = NULL;
5473 	int                     error = 0;
5474 	boolean_t               is_current_proc = FALSE;
5475 	struct proc_ident       pident = {0};
5476 
5477 	AUDIT_MACH_SYSCALL_ENTER(AUE_TASKFORPID);
5478 	AUDIT_ARG(pid, pid);
5479 	AUDIT_ARG(mach_port1, target_tport);
5480 
5481 	/* Always check if pid == 0 */
5482 	if (pid == 0) {
5483 		(void) copyout((char *)&tret, task_addr, sizeof(mach_port_name_t));
5484 		AUDIT_MACH_SYSCALL_EXIT(KERN_FAILURE);
5485 		return KERN_FAILURE;
5486 	}
5487 
5488 	t1 = port_name_to_task(target_tport);
5489 	if (t1 == TASK_NULL) {
5490 		(void) copyout((char *)&tret, task_addr, sizeof(mach_port_name_t));
5491 		AUDIT_MACH_SYSCALL_EXIT(KERN_FAILURE);
5492 		return KERN_FAILURE;
5493 	}
5494 
5495 
5496 	p = proc_find(pid);
5497 	if (p == PROC_NULL) {
5498 		error = KERN_FAILURE;
5499 		goto tfpout;
5500 	}
5501 	pident = proc_ident(p);
5502 	is_current_proc = (p == current_proc());
5503 
5504 #if CONFIG_AUDIT
5505 	AUDIT_ARG(process, p);
5506 #endif
5507 
5508 	if (!(task_for_pid_posix_check(p))) {
5509 		error = KERN_FAILURE;
5510 		goto tfpout;
5511 	}
5512 
5513 	if (proc_task(p) == TASK_NULL) {
5514 		error = KERN_SUCCESS;
5515 		goto tfpout;
5516 	}
5517 
5518 	/*
5519 	 * Grab a task reference and drop the proc reference as the proc ref
5520 	 * shouldn't be held accross upcalls.
5521 	 */
5522 	task = proc_task(p);
5523 	task_reference(task);
5524 
5525 	proc_rele(p);
5526 	p = PROC_NULL;
5527 
5528 	/* IPC is not active on the task until after `exec_resettextvp` has been called.
5529 	 * We don't want to call into MAC hooks until we know that this has occured, otherwise
5530 	 * AMFI and others will read uninitialized fields from the csproc
5531 	 */
5532 	if (!task_is_ipc_active(task)) {
5533 		error = KERN_FAILURE;
5534 		goto tfpout;
5535 	}
5536 
5537 #if CONFIG_MACF
5538 	error = mac_proc_check_get_task(kauth_cred_get(), &pident, TASK_FLAVOR_CONTROL);
5539 	if (error) {
5540 		error = KERN_FAILURE;
5541 		goto tfpout;
5542 	}
5543 #endif
5544 
5545 	/* If we aren't root and target's task access port is set... */
5546 	if (!kauth_cred_issuser(kauth_cred_get()) &&
5547 	    !is_current_proc &&
5548 	    (task_get_task_access_port(task, &tfpport) == 0) &&
5549 	    (tfpport != IPC_PORT_NULL)) {
5550 		if (tfpport == IPC_PORT_DEAD) {
5551 			error = KERN_PROTECTION_FAILURE;
5552 			goto tfpout;
5553 		}
5554 
5555 		/* Call up to the task access server */
5556 		error = __KERNEL_WAITING_ON_TASKGATED_CHECK_ACCESS_UPCALL__(tfpport,
5557 		    proc_selfpid(), kauth_getgid(), pid, TASK_FLAVOR_CONTROL);
5558 
5559 		if (error != MACH_MSG_SUCCESS) {
5560 			if (error == MACH_RCV_INTERRUPTED) {
5561 				error = KERN_ABORTED;
5562 			} else {
5563 				error = KERN_FAILURE;
5564 			}
5565 			goto tfpout;
5566 		}
5567 	}
5568 
5569 	/* Grant task port access */
5570 	extmod_statistics_incr_task_for_pid(task);
5571 
5572 	/* this reference will be consumed during conversion */
5573 	task_reference(task);
5574 	if (task == current_task()) {
5575 		/* return pinned self if current_task() so equality check with mach_task_self_ passes */
5576 		sright = (void *)convert_task_to_port_pinned(task);
5577 	} else {
5578 		sright = (void *)convert_task_to_port(task);
5579 	}
5580 	/* extra task ref consumed */
5581 
5582 	/*
5583 	 * Check if the task has been corpsified. We must do so after conversion
5584 	 * since we don't hold locks and may have grabbed a corpse control port
5585 	 * above which will prevent no-senders notification delivery.
5586 	 */
5587 	if (task_is_a_corpse(task)) {
5588 		ipc_port_release_send(sright);
5589 		error = KERN_FAILURE;
5590 		goto tfpout;
5591 	}
5592 
5593 	tret = ipc_port_copyout_send(
5594 		sright,
5595 		get_task_ipcspace(current_task()));
5596 
5597 	error = KERN_SUCCESS;
5598 
5599 tfpout:
5600 	task_deallocate(t1);
5601 	AUDIT_ARG(mach_port2, tret);
5602 	(void) copyout((char *) &tret, task_addr, sizeof(mach_port_name_t));
5603 
5604 	if (tfpport != IPC_PORT_NULL) {
5605 		ipc_port_release_send(tfpport);
5606 	}
5607 	if (task != TASK_NULL) {
5608 		task_deallocate(task);
5609 	}
5610 	if (p != PROC_NULL) {
5611 		proc_rele(p);
5612 	}
5613 	AUDIT_MACH_SYSCALL_EXIT(error);
5614 	return error;
5615 }
5616 
5617 /*
5618  *	Routine:	task_name_for_pid
5619  *	Purpose:
5620  *		Get the task name port for another "process", named by its
5621  *		process ID on the same host as "target_task".
5622  *
5623  *		Only permitted to privileged processes, or processes
5624  *		with the same user ID.
5625  *
5626  * XXX This should be a BSD system call, not a Mach trap!!!
5627  */
5628 
5629 kern_return_t
task_name_for_pid(struct task_name_for_pid_args * args)5630 task_name_for_pid(
5631 	struct task_name_for_pid_args *args)
5632 {
5633 	mach_port_name_t        target_tport = args->target_tport;
5634 	int                     pid = args->pid;
5635 	user_addr_t             task_addr = args->t;
5636 	proc_t                  p = PROC_NULL;
5637 	task_t                  t1 = TASK_NULL;
5638 	mach_port_name_t        tret = MACH_PORT_NULL;
5639 	void * sright;
5640 	int error = 0, refheld = 0;
5641 	kauth_cred_t target_cred;
5642 
5643 	AUDIT_MACH_SYSCALL_ENTER(AUE_TASKNAMEFORPID);
5644 	AUDIT_ARG(pid, pid);
5645 	AUDIT_ARG(mach_port1, target_tport);
5646 
5647 	t1 = port_name_to_task(target_tport);
5648 	if (t1 == TASK_NULL) {
5649 		(void) copyout((char *)&tret, task_addr, sizeof(mach_port_name_t));
5650 		AUDIT_MACH_SYSCALL_EXIT(KERN_FAILURE);
5651 		return KERN_FAILURE;
5652 	}
5653 
5654 	p = proc_find(pid);
5655 	if (p != PROC_NULL) {
5656 		AUDIT_ARG(process, p);
5657 		target_cred = kauth_cred_proc_ref(p);
5658 		refheld = 1;
5659 
5660 		if ((p->p_stat != SZOMB)
5661 		    && ((current_proc() == p)
5662 		    || kauth_cred_issuser(kauth_cred_get())
5663 		    || ((kauth_cred_getuid(target_cred) == kauth_cred_getuid(kauth_cred_get())) &&
5664 		    ((kauth_cred_getruid(target_cred) == kauth_getruid())))
5665 		    || IOCurrentTaskHasEntitlement("com.apple.system-task-ports.name.safe")
5666 		    )) {
5667 			if (proc_task(p) != TASK_NULL) {
5668 				struct proc_ident pident = proc_ident(p);
5669 
5670 				task_t task = proc_task(p);
5671 
5672 				task_reference(task);
5673 				proc_rele(p);
5674 				p = PROC_NULL;
5675 #if CONFIG_MACF
5676 				error = mac_proc_check_get_task(kauth_cred_get(), &pident, TASK_FLAVOR_NAME);
5677 				if (error) {
5678 					task_deallocate(task);
5679 					goto noperm;
5680 				}
5681 #endif
5682 				sright = (void *)convert_task_name_to_port(task);
5683 				task = NULL;
5684 				tret = ipc_port_copyout_send(sright,
5685 				    get_task_ipcspace(current_task()));
5686 			} else {
5687 				tret  = MACH_PORT_NULL;
5688 			}
5689 
5690 			AUDIT_ARG(mach_port2, tret);
5691 			(void) copyout((char *)&tret, task_addr, sizeof(mach_port_name_t));
5692 			task_deallocate(t1);
5693 			error = KERN_SUCCESS;
5694 			goto tnfpout;
5695 		}
5696 	}
5697 
5698 #if CONFIG_MACF
5699 noperm:
5700 #endif
5701 	task_deallocate(t1);
5702 	tret = MACH_PORT_NULL;
5703 	(void) copyout((char *) &tret, task_addr, sizeof(mach_port_name_t));
5704 	error = KERN_FAILURE;
5705 tnfpout:
5706 	if (refheld != 0) {
5707 		kauth_cred_unref(&target_cred);
5708 	}
5709 	if (p != PROC_NULL) {
5710 		proc_rele(p);
5711 	}
5712 	AUDIT_MACH_SYSCALL_EXIT(error);
5713 	return error;
5714 }
5715 
5716 /*
5717  *	Routine:	task_inspect_for_pid
5718  *	Purpose:
5719  *		Get the task inspect port for another "process", named by its
5720  *		process ID on the same host as "target_task".
5721  */
5722 int
task_inspect_for_pid(struct proc * p __unused,struct task_inspect_for_pid_args * args,int * ret)5723 task_inspect_for_pid(struct proc *p __unused, struct task_inspect_for_pid_args *args, int *ret)
5724 {
5725 	mach_port_name_t        target_tport = args->target_tport;
5726 	int                     pid = args->pid;
5727 	user_addr_t             task_addr = args->t;
5728 
5729 	proc_t                  proc = PROC_NULL;
5730 	task_t                  t1 = TASK_NULL;
5731 	task_inspect_t          task_insp = TASK_INSPECT_NULL;
5732 	mach_port_name_t        tret = MACH_PORT_NULL;
5733 	ipc_port_t              tfpport = MACH_PORT_NULL;
5734 	int                     error = 0;
5735 	void                    *sright = NULL;
5736 	boolean_t               is_current_proc = FALSE;
5737 	struct proc_ident       pident = {0};
5738 
5739 	/* Disallow inspect port for kernel_task */
5740 	if (pid == 0) {
5741 		(void) copyout((char *)&tret, task_addr, sizeof(mach_port_name_t));
5742 		return EPERM;
5743 	}
5744 
5745 	t1 = port_name_to_task(target_tport);
5746 	if (t1 == TASK_NULL) {
5747 		(void) copyout((char *) &tret, task_addr, sizeof(mach_port_name_t));
5748 		return EINVAL;
5749 	}
5750 
5751 	proc = proc_find(pid);
5752 	if (proc == PROC_NULL) {
5753 		error = ESRCH;
5754 		goto tifpout;
5755 	}
5756 	pident = proc_ident(proc);
5757 	is_current_proc = (proc == current_proc());
5758 
5759 	if (!(task_for_pid_posix_check(proc))) {
5760 		error = EPERM;
5761 		goto tifpout;
5762 	}
5763 
5764 	task_insp = proc_task(proc);
5765 	if (task_insp == TASK_INSPECT_NULL) {
5766 		goto tifpout;
5767 	}
5768 
5769 	/*
5770 	 * Grab a task reference and drop the proc reference before making any upcalls.
5771 	 */
5772 	task_reference(task_insp);
5773 
5774 	proc_rele(proc);
5775 	proc = PROC_NULL;
5776 
5777 #if CONFIG_MACF
5778 	error = mac_proc_check_get_task(kauth_cred_get(), &pident, TASK_FLAVOR_INSPECT);
5779 	if (error) {
5780 		error = EPERM;
5781 		goto tifpout;
5782 	}
5783 #endif
5784 
5785 	/* If we aren't root and target's task access port is set... */
5786 	if (!kauth_cred_issuser(kauth_cred_get()) &&
5787 	    !is_current_proc &&
5788 	    (task_get_task_access_port(task_insp, &tfpport) == 0) &&
5789 	    (tfpport != IPC_PORT_NULL)) {
5790 		if (tfpport == IPC_PORT_DEAD) {
5791 			error = EACCES;
5792 			goto tifpout;
5793 		}
5794 
5795 
5796 		/* Call up to the task access server */
5797 		error = __KERNEL_WAITING_ON_TASKGATED_CHECK_ACCESS_UPCALL__(tfpport,
5798 		    proc_selfpid(), kauth_getgid(), pid, TASK_FLAVOR_INSPECT);
5799 
5800 		if (error != MACH_MSG_SUCCESS) {
5801 			if (error == MACH_RCV_INTERRUPTED) {
5802 				error = EINTR;
5803 			} else {
5804 				error = EPERM;
5805 			}
5806 			goto tifpout;
5807 		}
5808 	}
5809 
5810 	/* Check if the task has been corpsified */
5811 	if (task_is_a_corpse(task_insp)) {
5812 		error = EACCES;
5813 		goto tifpout;
5814 	}
5815 
5816 	/* could be IP_NULL, consumes a ref */
5817 	sright = (void*) convert_task_inspect_to_port(task_insp);
5818 	task_insp = TASK_INSPECT_NULL;
5819 	tret = ipc_port_copyout_send(sright, get_task_ipcspace(current_task()));
5820 
5821 tifpout:
5822 	task_deallocate(t1);
5823 	(void) copyout((char *) &tret, task_addr, sizeof(mach_port_name_t));
5824 	if (proc != PROC_NULL) {
5825 		proc_rele(proc);
5826 	}
5827 	if (tfpport != IPC_PORT_NULL) {
5828 		ipc_port_release_send(tfpport);
5829 	}
5830 	if (task_insp != TASK_INSPECT_NULL) {
5831 		task_deallocate(task_insp);
5832 	}
5833 
5834 	*ret = error;
5835 	return error;
5836 }
5837 
5838 /*
5839  *	Routine:	task_read_for_pid
5840  *	Purpose:
5841  *		Get the task read port for another "process", named by its
5842  *		process ID on the same host as "target_task".
5843  */
5844 int
task_read_for_pid(struct proc * p __unused,struct task_read_for_pid_args * args,int * ret)5845 task_read_for_pid(struct proc *p __unused, struct task_read_for_pid_args *args, int *ret)
5846 {
5847 	mach_port_name_t        target_tport = args->target_tport;
5848 	int                     pid = args->pid;
5849 	user_addr_t             task_addr = args->t;
5850 
5851 	proc_t                  proc = PROC_NULL;
5852 	task_t                  t1 = TASK_NULL;
5853 	task_read_t             task_read = TASK_READ_NULL;
5854 	mach_port_name_t        tret = MACH_PORT_NULL;
5855 	ipc_port_t              tfpport = MACH_PORT_NULL;
5856 	int                     error = 0;
5857 	void                    *sright = NULL;
5858 	boolean_t               is_current_proc = FALSE;
5859 	struct proc_ident       pident = {0};
5860 
5861 	/* Disallow read port for kernel_task */
5862 	if (pid == 0) {
5863 		(void) copyout((char *)&tret, task_addr, sizeof(mach_port_name_t));
5864 		return EPERM;
5865 	}
5866 
5867 	t1 = port_name_to_task(target_tport);
5868 	if (t1 == TASK_NULL) {
5869 		(void) copyout((char *)&tret, task_addr, sizeof(mach_port_name_t));
5870 		return EINVAL;
5871 	}
5872 
5873 	proc = proc_find(pid);
5874 	if (proc == PROC_NULL) {
5875 		error = ESRCH;
5876 		goto trfpout;
5877 	}
5878 	pident = proc_ident(proc);
5879 	is_current_proc = (proc == current_proc());
5880 
5881 	if (!(task_for_pid_posix_check(proc))) {
5882 		error = EPERM;
5883 		goto trfpout;
5884 	}
5885 
5886 	task_read = proc_task(proc);
5887 	if (task_read == TASK_INSPECT_NULL) {
5888 		goto trfpout;
5889 	}
5890 
5891 	/*
5892 	 * Grab a task reference and drop the proc reference before making any upcalls.
5893 	 */
5894 	task_reference(task_read);
5895 
5896 	proc_rele(proc);
5897 	proc = PROC_NULL;
5898 
5899 #if CONFIG_MACF
5900 	error = mac_proc_check_get_task(kauth_cred_get(), &pident, TASK_FLAVOR_READ);
5901 	if (error) {
5902 		error = EPERM;
5903 		goto trfpout;
5904 	}
5905 #endif
5906 
5907 	/* If we aren't root and target's task access port is set... */
5908 	if (!kauth_cred_issuser(kauth_cred_get()) &&
5909 	    !is_current_proc &&
5910 	    (task_get_task_access_port(task_read, &tfpport) == 0) &&
5911 	    (tfpport != IPC_PORT_NULL)) {
5912 		if (tfpport == IPC_PORT_DEAD) {
5913 			error = EACCES;
5914 			goto trfpout;
5915 		}
5916 
5917 
5918 		/* Call up to the task access server */
5919 		error = __KERNEL_WAITING_ON_TASKGATED_CHECK_ACCESS_UPCALL__(tfpport,
5920 		    proc_selfpid(), kauth_getgid(), pid, TASK_FLAVOR_READ);
5921 
5922 		if (error != MACH_MSG_SUCCESS) {
5923 			if (error == MACH_RCV_INTERRUPTED) {
5924 				error = EINTR;
5925 			} else {
5926 				error = EPERM;
5927 			}
5928 			goto trfpout;
5929 		}
5930 	}
5931 
5932 	/* Check if the task has been corpsified */
5933 	if (task_is_a_corpse(task_read)) {
5934 		error = EACCES;
5935 		goto trfpout;
5936 	}
5937 
5938 	/* could be IP_NULL, consumes a ref */
5939 	sright = (void*) convert_task_read_to_port(task_read);
5940 	task_read = TASK_READ_NULL;
5941 	tret = ipc_port_copyout_send(sright, get_task_ipcspace(current_task()));
5942 
5943 trfpout:
5944 	task_deallocate(t1);
5945 	(void) copyout((char *) &tret, task_addr, sizeof(mach_port_name_t));
5946 	if (proc != PROC_NULL) {
5947 		proc_rele(proc);
5948 	}
5949 	if (tfpport != IPC_PORT_NULL) {
5950 		ipc_port_release_send(tfpport);
5951 	}
5952 	if (task_read != TASK_READ_NULL) {
5953 		task_deallocate(task_read);
5954 	}
5955 
5956 	*ret = error;
5957 	return error;
5958 }
5959 
5960 kern_return_t
pid_suspend(struct proc * p __unused,struct pid_suspend_args * args,int * ret)5961 pid_suspend(struct proc *p __unused, struct pid_suspend_args *args, int *ret)
5962 {
5963 	task_t  target = NULL;
5964 	proc_t  targetproc = PROC_NULL;
5965 	int     pid = args->pid;
5966 	int     error = 0;
5967 	mach_port_t tfpport = MACH_PORT_NULL;
5968 
5969 	if (pid == 0) {
5970 		error = EPERM;
5971 		goto out;
5972 	}
5973 
5974 	targetproc = proc_find(pid);
5975 	if (targetproc == PROC_NULL) {
5976 		error = ESRCH;
5977 		goto out;
5978 	}
5979 
5980 	if (!task_for_pid_posix_check(targetproc) &&
5981 	    !IOCurrentTaskHasEntitlement(PROCESS_RESUME_SUSPEND_ENTITLEMENT)) {
5982 		error = EPERM;
5983 		goto out;
5984 	}
5985 
5986 #if CONFIG_MACF
5987 	error = mac_proc_check_suspend_resume(targetproc, MAC_PROC_CHECK_SUSPEND);
5988 	if (error) {
5989 		error = EPERM;
5990 		goto out;
5991 	}
5992 #endif
5993 
5994 	target = proc_task(targetproc);
5995 #if XNU_TARGET_OS_OSX
5996 	if (target != TASK_NULL) {
5997 		/* If we aren't root and target's task access port is set... */
5998 		if (!kauth_cred_issuser(kauth_cred_get()) &&
5999 		    targetproc != current_proc() &&
6000 		    (task_get_task_access_port(target, &tfpport) == 0) &&
6001 		    (tfpport != IPC_PORT_NULL)) {
6002 			if (tfpport == IPC_PORT_DEAD) {
6003 				error = EACCES;
6004 				goto out;
6005 			}
6006 
6007 			/* Call up to the task access server */
6008 			error = __KERNEL_WAITING_ON_TASKGATED_CHECK_ACCESS_UPCALL__(tfpport,
6009 			    proc_selfpid(), kauth_getgid(), pid, TASK_FLAVOR_CONTROL);
6010 
6011 			if (error != MACH_MSG_SUCCESS) {
6012 				if (error == MACH_RCV_INTERRUPTED) {
6013 					error = EINTR;
6014 				} else {
6015 					error = EPERM;
6016 				}
6017 				goto out;
6018 			}
6019 		}
6020 	}
6021 #endif /* XNU_TARGET_OS_OSX */
6022 
6023 	task_reference(target);
6024 	error = task_pidsuspend(target);
6025 	if (error) {
6026 		if (error == KERN_INVALID_ARGUMENT) {
6027 			error = EINVAL;
6028 		} else {
6029 			error = EPERM;
6030 		}
6031 	}
6032 #if CONFIG_MEMORYSTATUS
6033 	else {
6034 		memorystatus_on_suspend(targetproc);
6035 	}
6036 #endif
6037 
6038 	task_deallocate(target);
6039 
6040 out:
6041 	if (tfpport != IPC_PORT_NULL) {
6042 		ipc_port_release_send(tfpport);
6043 	}
6044 
6045 	if (targetproc != PROC_NULL) {
6046 		proc_rele(targetproc);
6047 	}
6048 	*ret = error;
6049 	return error;
6050 }
6051 
6052 kern_return_t
debug_control_port_for_pid(struct debug_control_port_for_pid_args * args)6053 debug_control_port_for_pid(struct debug_control_port_for_pid_args *args)
6054 {
6055 	mach_port_name_t        target_tport = args->target_tport;
6056 	int                     pid = args->pid;
6057 	user_addr_t             task_addr = args->t;
6058 	proc_t                  p = PROC_NULL;
6059 	task_t                  t1 = TASK_NULL;
6060 	task_t                  task = TASK_NULL;
6061 	mach_port_name_t        tret = MACH_PORT_NULL;
6062 	ipc_port_t              tfpport = MACH_PORT_NULL;
6063 	ipc_port_t              sright = NULL;
6064 	int                     error = 0;
6065 	boolean_t               is_current_proc = FALSE;
6066 	struct proc_ident       pident = {0};
6067 
6068 	AUDIT_MACH_SYSCALL_ENTER(AUE_DBGPORTFORPID);
6069 	AUDIT_ARG(pid, pid);
6070 	AUDIT_ARG(mach_port1, target_tport);
6071 
6072 	/* Always check if pid == 0 */
6073 	if (pid == 0) {
6074 		(void) copyout((char *)&tret, task_addr, sizeof(mach_port_name_t));
6075 		AUDIT_MACH_SYSCALL_EXIT(KERN_FAILURE);
6076 		return KERN_FAILURE;
6077 	}
6078 
6079 	t1 = port_name_to_task(target_tport);
6080 	if (t1 == TASK_NULL) {
6081 		(void) copyout((char *)&tret, task_addr, sizeof(mach_port_name_t));
6082 		AUDIT_MACH_SYSCALL_EXIT(KERN_FAILURE);
6083 		return KERN_FAILURE;
6084 	}
6085 
6086 	p = proc_find(pid);
6087 	if (p == PROC_NULL) {
6088 		error = KERN_FAILURE;
6089 		goto tfpout;
6090 	}
6091 	pident = proc_ident(p);
6092 	is_current_proc = (p == current_proc());
6093 
6094 #if CONFIG_AUDIT
6095 	AUDIT_ARG(process, p);
6096 #endif
6097 
6098 	if (!(task_for_pid_posix_check(p))) {
6099 		error = KERN_FAILURE;
6100 		goto tfpout;
6101 	}
6102 
6103 	if (proc_task(p) == TASK_NULL) {
6104 		error = KERN_SUCCESS;
6105 		goto tfpout;
6106 	}
6107 
6108 	/*
6109 	 * Grab a task reference and drop the proc reference before making any upcalls.
6110 	 */
6111 	task = proc_task(p);
6112 	task_reference(task);
6113 
6114 	proc_rele(p);
6115 	p = PROC_NULL;
6116 
6117 	if (!IOCurrentTaskHasEntitlement(DEBUG_PORT_ENTITLEMENT)) {
6118 #if CONFIG_MACF
6119 		error = mac_proc_check_get_task(kauth_cred_get(), &pident, TASK_FLAVOR_CONTROL);
6120 		if (error) {
6121 			error = KERN_FAILURE;
6122 			goto tfpout;
6123 		}
6124 #endif
6125 
6126 		/* If we aren't root and target's task access port is set... */
6127 		if (!kauth_cred_issuser(kauth_cred_get()) &&
6128 		    !is_current_proc &&
6129 		    (task_get_task_access_port(task, &tfpport) == 0) &&
6130 		    (tfpport != IPC_PORT_NULL)) {
6131 			if (tfpport == IPC_PORT_DEAD) {
6132 				error = KERN_PROTECTION_FAILURE;
6133 				goto tfpout;
6134 			}
6135 
6136 
6137 			/* Call up to the task access server */
6138 			error = __KERNEL_WAITING_ON_TASKGATED_CHECK_ACCESS_UPCALL__(tfpport,
6139 			    proc_selfpid(), kauth_getgid(), pid, TASK_FLAVOR_CONTROL);
6140 
6141 			if (error != MACH_MSG_SUCCESS) {
6142 				if (error == MACH_RCV_INTERRUPTED) {
6143 					error = KERN_ABORTED;
6144 				} else {
6145 					error = KERN_FAILURE;
6146 				}
6147 				goto tfpout;
6148 			}
6149 		}
6150 	}
6151 
6152 	/* Check if the task has been corpsified */
6153 	if (task_is_a_corpse(task)) {
6154 		error = KERN_FAILURE;
6155 		goto tfpout;
6156 	}
6157 
6158 	error = task_get_debug_control_port(task, &sright);
6159 	if (error != KERN_SUCCESS) {
6160 		goto tfpout;
6161 	}
6162 
6163 	tret = ipc_port_copyout_send(
6164 		sright,
6165 		get_task_ipcspace(current_task()));
6166 
6167 	error = KERN_SUCCESS;
6168 
6169 tfpout:
6170 	task_deallocate(t1);
6171 	AUDIT_ARG(mach_port2, tret);
6172 	(void) copyout((char *) &tret, task_addr, sizeof(mach_port_name_t));
6173 
6174 	if (tfpport != IPC_PORT_NULL) {
6175 		ipc_port_release_send(tfpport);
6176 	}
6177 	if (task != TASK_NULL) {
6178 		task_deallocate(task);
6179 	}
6180 	if (p != PROC_NULL) {
6181 		proc_rele(p);
6182 	}
6183 	AUDIT_MACH_SYSCALL_EXIT(error);
6184 	return error;
6185 }
6186 
6187 kern_return_t
pid_resume(struct proc * p __unused,struct pid_resume_args * args,int * ret)6188 pid_resume(struct proc *p __unused, struct pid_resume_args *args, int *ret)
6189 {
6190 	task_t  target = NULL;
6191 	proc_t  targetproc = PROC_NULL;
6192 	int     pid = args->pid;
6193 	int     error = 0;
6194 	mach_port_t tfpport = MACH_PORT_NULL;
6195 
6196 	if (pid == 0) {
6197 		error = EPERM;
6198 		goto out;
6199 	}
6200 
6201 	targetproc = proc_find(pid);
6202 	if (targetproc == PROC_NULL) {
6203 		error = ESRCH;
6204 		goto out;
6205 	}
6206 
6207 	if (!task_for_pid_posix_check(targetproc) &&
6208 	    !IOCurrentTaskHasEntitlement(PROCESS_RESUME_SUSPEND_ENTITLEMENT)) {
6209 		error = EPERM;
6210 		goto out;
6211 	}
6212 
6213 #if CONFIG_MACF
6214 	error = mac_proc_check_suspend_resume(targetproc, MAC_PROC_CHECK_RESUME);
6215 	if (error) {
6216 		error = EPERM;
6217 		goto out;
6218 	}
6219 #endif
6220 
6221 	target = proc_task(targetproc);
6222 #if XNU_TARGET_OS_OSX
6223 	if (target != TASK_NULL) {
6224 		/* If we aren't root and target's task access port is set... */
6225 		if (!kauth_cred_issuser(kauth_cred_get()) &&
6226 		    targetproc != current_proc() &&
6227 		    (task_get_task_access_port(target, &tfpport) == 0) &&
6228 		    (tfpport != IPC_PORT_NULL)) {
6229 			if (tfpport == IPC_PORT_DEAD) {
6230 				error = EACCES;
6231 				goto out;
6232 			}
6233 
6234 			/* Call up to the task access server */
6235 			error = __KERNEL_WAITING_ON_TASKGATED_CHECK_ACCESS_UPCALL__(tfpport,
6236 			    proc_selfpid(), kauth_getgid(), pid, TASK_FLAVOR_CONTROL);
6237 
6238 			if (error != MACH_MSG_SUCCESS) {
6239 				if (error == MACH_RCV_INTERRUPTED) {
6240 					error = EINTR;
6241 				} else {
6242 					error = EPERM;
6243 				}
6244 				goto out;
6245 			}
6246 		}
6247 	}
6248 #endif /* XNU_TARGET_OS_OSX */
6249 
6250 #if !XNU_TARGET_OS_OSX
6251 #if SOCKETS
6252 	resume_proc_sockets(targetproc);
6253 #endif /* SOCKETS */
6254 #endif /* !XNU_TARGET_OS_OSX */
6255 
6256 	task_reference(target);
6257 
6258 #if CONFIG_MEMORYSTATUS
6259 	memorystatus_on_resume(targetproc);
6260 #endif
6261 
6262 	error = task_pidresume(target);
6263 	if (error) {
6264 		if (error == KERN_INVALID_ARGUMENT) {
6265 			error = EINVAL;
6266 		} else {
6267 			if (error == KERN_MEMORY_ERROR) {
6268 				psignal(targetproc, SIGKILL);
6269 				error = EIO;
6270 			} else {
6271 				error = EPERM;
6272 			}
6273 		}
6274 	}
6275 
6276 	task_deallocate(target);
6277 
6278 out:
6279 	if (tfpport != IPC_PORT_NULL) {
6280 		ipc_port_release_send(tfpport);
6281 	}
6282 
6283 	if (targetproc != PROC_NULL) {
6284 		proc_rele(targetproc);
6285 	}
6286 
6287 	*ret = error;
6288 	return error;
6289 }
6290 
6291 #if !XNU_TARGET_OS_OSX
6292 /*
6293  * Freeze the specified process (provided in args->pid), or find and freeze a PID.
6294  * When a process is specified, this call is blocking, otherwise we wake up the
6295  * freezer thread and do not block on a process being frozen.
6296  */
6297 int
pid_hibernate(struct proc * p __unused,struct pid_hibernate_args * args,int * ret)6298 pid_hibernate(struct proc *p __unused, struct pid_hibernate_args *args, int *ret)
6299 {
6300 	int     error = 0;
6301 	proc_t  targetproc = PROC_NULL;
6302 	int     pid = args->pid;
6303 
6304 	/*
6305 	 * TODO: Create a different interface for compressor sweeps,
6306 	 * gated by an entitlement: rdar://116490432
6307 	 */
6308 	if (pid == -2) {
6309 		error = mach_to_bsd_errno(vm_pageout_anonymous_pages());
6310 	}
6311 
6312 #ifndef CONFIG_FREEZE
6313 	if (pid != -2) {
6314 		os_log(OS_LOG_DEFAULT, "%s: pid %d not supported when freezer is disabled.",
6315 		    __func__, pid);
6316 		error = ENOTSUP;
6317 	}
6318 #else
6319 
6320 	/*
6321 	 * If a pid has been provided, we obtain the process handle and call task_for_pid_posix_check().
6322 	 */
6323 
6324 	if (pid >= 0) {
6325 		targetproc = proc_find(pid);
6326 
6327 		if (targetproc == PROC_NULL) {
6328 			error = ESRCH;
6329 			goto out;
6330 		}
6331 
6332 		if (!task_for_pid_posix_check(targetproc)) {
6333 			error = EPERM;
6334 			goto out;
6335 		}
6336 	}
6337 
6338 #if CONFIG_MACF
6339 	//Note that targetproc may be null
6340 	error = mac_proc_check_suspend_resume(targetproc, MAC_PROC_CHECK_HIBERNATE);
6341 	if (error) {
6342 		error = EPERM;
6343 		goto out;
6344 	}
6345 #endif
6346 
6347 	if (pid == -1) {
6348 		memorystatus_on_inactivity(targetproc);
6349 	} else if (pid >= 0) {
6350 		error = memorystatus_freeze_process_sync(targetproc);
6351 	}
6352 	/* We already handled the pid == -2 case */
6353 
6354 out:
6355 
6356 #endif /* CONFIG_FREEZE */
6357 
6358 	if (targetproc != PROC_NULL) {
6359 		proc_rele(targetproc);
6360 	}
6361 	*ret = error;
6362 	return error;
6363 }
6364 #endif /* !XNU_TARGET_OS_OSX */
6365 
6366 #if SOCKETS
6367 
6368 #if SKYWALK
6369 /*
6370  * Since we make multiple passes across the fileproc array, record the
6371  * first MAX_CHANNELS channel handles found.  MAX_CHANNELS should be
6372  * large enough to accomodate most, if not all cases.  If we find more,
6373  * we'll go to the slow path during second pass.
6374  */
6375 #define MAX_CHANNELS    8       /* should be more than enough */
6376 #endif /* SKYWALK */
6377 
6378 static int
networking_defunct_callout(proc_t p,void * arg)6379 networking_defunct_callout(proc_t p, void *arg)
6380 {
6381 	struct pid_shutdown_sockets_args *args = arg;
6382 	int pid = args->pid;
6383 	int level = args->level;
6384 	struct fileproc *fp;
6385 #if SKYWALK
6386 	int i;
6387 	int channel_count = 0;
6388 	struct kern_channel *channel_array[MAX_CHANNELS];
6389 
6390 	bzero(&channel_array, sizeof(channel_array));
6391 
6392 	sk_protect_t protect = sk_async_transmit_protect();
6393 #endif /* SKYWALK */
6394 
6395 	proc_fdlock(p);
6396 
6397 	fdt_foreach(fp, p) {
6398 		struct fileglob *fg = fp->fp_glob;
6399 
6400 		switch (FILEGLOB_DTYPE(fg)) {
6401 		case DTYPE_SOCKET: {
6402 			struct socket *so = (struct socket *)fg_get_data(fg);
6403 			if (proc_getpid(p) == pid || so->last_pid == pid ||
6404 			    ((so->so_flags & SOF_DELEGATED) && so->e_pid == pid)) {
6405 				/* Call networking stack with socket and level */
6406 				(void)socket_defunct(p, so, level);
6407 			}
6408 			break;
6409 		}
6410 #if NECP
6411 		case DTYPE_NETPOLICY:
6412 			/* first pass: defunct necp and get stats for ntstat */
6413 			if (proc_getpid(p) == pid) {
6414 				necp_fd_defunct(p,
6415 				    (struct necp_fd_data *)fg_get_data(fg));
6416 			}
6417 			break;
6418 #endif /* NECP */
6419 #if SKYWALK
6420 		case DTYPE_CHANNEL:
6421 			/* first pass: get channels and total count */
6422 			if (proc_getpid(p) == pid) {
6423 				if (channel_count < MAX_CHANNELS) {
6424 					channel_array[channel_count] =
6425 					    (struct kern_channel *)fg_get_data(fg);
6426 				}
6427 				++channel_count;
6428 			}
6429 			break;
6430 #endif /* SKYWALK */
6431 		default:
6432 			break;
6433 		}
6434 	}
6435 
6436 #if SKYWALK
6437 	/*
6438 	 * Second pass: defunct channels/flows (after NECP).  Handle
6439 	 * the common case of up to MAX_CHANNELS count with fast path,
6440 	 * and traverse the fileproc array again only if we exceed it.
6441 	 */
6442 	if (channel_count != 0 && channel_count <= MAX_CHANNELS) {
6443 		ASSERT(proc_getpid(p) == pid);
6444 		for (i = 0; i < channel_count; i++) {
6445 			ASSERT(channel_array[i] != NULL);
6446 			kern_channel_defunct(p, channel_array[i]);
6447 		}
6448 	} else if (channel_count != 0) {
6449 		ASSERT(proc_getpid(p) == pid);
6450 		fdt_foreach(fp, p) {
6451 			struct fileglob *fg = fp->fp_glob;
6452 
6453 			if (FILEGLOB_DTYPE(fg) == DTYPE_CHANNEL) {
6454 				kern_channel_defunct(p,
6455 				    (struct kern_channel *)fg_get_data(fg));
6456 			}
6457 		}
6458 	}
6459 
6460 	sk_async_transmit_unprotect(protect);
6461 #endif /* SKYWALK */
6462 
6463 	proc_fdunlock(p);
6464 
6465 	return PROC_RETURNED;
6466 }
6467 
6468 int
pid_shutdown_sockets(struct proc * p __unused,struct pid_shutdown_sockets_args * args,int * ret)6469 pid_shutdown_sockets(struct proc *p __unused, struct pid_shutdown_sockets_args *args, int *ret)
6470 {
6471 	int                             error = 0;
6472 	proc_t                          targetproc = PROC_NULL;
6473 	int                             pid = args->pid;
6474 	int                             level = args->level;
6475 
6476 	if (level != SHUTDOWN_SOCKET_LEVEL_DISCONNECT_SVC &&
6477 	    level != SHUTDOWN_SOCKET_LEVEL_DISCONNECT_ALL) {
6478 		error = EINVAL;
6479 		goto out;
6480 	}
6481 
6482 	targetproc = proc_find(pid);
6483 	if (targetproc == PROC_NULL) {
6484 		error = ESRCH;
6485 		goto out;
6486 	}
6487 
6488 	if (!task_for_pid_posix_check(targetproc) &&
6489 	    !IOCurrentTaskHasEntitlement(PROCESS_RESUME_SUSPEND_ENTITLEMENT)) {
6490 		error = EPERM;
6491 		goto out;
6492 	}
6493 
6494 #if CONFIG_MACF
6495 	error = mac_proc_check_suspend_resume(targetproc, MAC_PROC_CHECK_SHUTDOWN_SOCKETS);
6496 	if (error) {
6497 		error = EPERM;
6498 		goto out;
6499 	}
6500 #endif
6501 
6502 	proc_iterate(PROC_ALLPROCLIST | PROC_NOWAITTRANS,
6503 	    networking_defunct_callout, args, NULL, NULL);
6504 
6505 out:
6506 	if (targetproc != PROC_NULL) {
6507 		proc_rele(targetproc);
6508 	}
6509 	*ret = error;
6510 	return error;
6511 }
6512 
6513 #endif /* SOCKETS */
6514 
6515 #if DEVELOPMENT || DEBUG
6516 /*
6517  * PT: Sadly this needs to be in bsd/ as SYSCTL_ macros aren't easily usable from
6518  * osfmk/. Ideally this sysctl would live in corpse_info.c
6519  */
6520 extern uint32_t total_corpses_allowed;
6521 SYSCTL_UINT(_kern, OID_AUTO, total_corpses_allowed,
6522     CTLFLAG_RW | CTLFLAG_LOCKED, &total_corpses_allowed, DEFAULT_TOTAL_CORPSES_ALLOWED,
6523     "Maximum in-flight corpse count");
6524 #endif /* DEVELOPMENT || DEBUG */
6525