xref: /xnu-8019.80.24/bsd/kern/kern_proc.c (revision a325d9c4a84054e40bbe985afedcb50ab80993ea)
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/kalloc.h>
101 #include <kern/task.h>
102 #include <kern/coalition.h>
103 #include <sys/coalition.h>
104 #include <kern/assert.h>
105 #include <kern/sched_prim.h>
106 #include <vm/vm_protos.h>
107 #include <vm/vm_map.h>          /* vm_map_switch_protect() */
108 #include <vm/vm_pageout.h>
109 #include <mach/task.h>
110 #include <mach/message.h>
111 #include <sys/priv.h>
112 #include <sys/proc_info.h>
113 #include <sys/bsdtask_info.h>
114 #include <sys/persona.h>
115 #include <sys/sysent.h>
116 #include <sys/reason.h>
117 #include <sys/proc_require.h>
118 #include <IOKit/IOBSD.h>        /* IOTaskHasEntitlement() */
119 #include <kern/ipc_kobject.h>   /* ipc_kobject_set_kobjidx() */
120 #include <kern/ast.h>           /* proc_filedesc_ast */
121 #include <libkern/amfi/amfi.h>
122 #include <mach-o/loader.h>
123 
124 #ifdef CONFIG_32BIT_TELEMETRY
125 #include <sys/kasl.h>
126 #endif /* CONFIG_32BIT_TELEMETRY */
127 
128 #if CONFIG_CSR
129 #include <sys/csr.h>
130 #endif
131 
132 #include <sys/kern_memorystatus.h>
133 
134 #if CONFIG_MACF
135 #include <security/mac_framework.h>
136 #include <security/mac_mach_internal.h>
137 #endif
138 
139 #include <libkern/crypto/sha1.h>
140 
141 #ifdef CONFIG_32BIT_TELEMETRY
142 #define MAX_32BIT_EXEC_SIG_SIZE 160
143 #endif /* CONFIG_32BIT_TELEMETRY */
144 
145 /*
146  * Structure associated with user cacheing.
147  */
148 struct uidinfo {
149 	LIST_ENTRY(uidinfo) ui_hash;
150 	uid_t   ui_uid;
151 	size_t    ui_proccnt;
152 };
153 #define UIHASH(uid)     (&uihashtbl[(uid) & uihash])
154 static LIST_HEAD(uihashhead, uidinfo) * uihashtbl;
155 static u_long uihash;          /* size of hash table - 1 */
156 
157 /*
158  * Other process lists
159  */
160 #define PIDHASH(pid)    (&pidhashtbl[(pid) & pidhash])
161 static SECURITY_READ_ONLY_LATE(struct proc_hp *) pidhashtbl;
162 static SECURITY_READ_ONLY_LATE(u_long) pidhash;
163 #define PGRPHASH(pgid)  (&pgrphashtbl[(pgid) & pgrphash])
164 static SECURITY_READ_ONLY_LATE(struct pgrp_hp *) pgrphashtbl;
165 static SECURITY_READ_ONLY_LATE(u_long) pgrphash;
166 SECURITY_READ_ONLY_LATE(struct sesshashhead *) sesshashtbl;
167 SECURITY_READ_ONLY_LATE(u_long) sesshash;
168 
169 #if PROC_REF_DEBUG
170 /* disable panics on leaked proc refs across syscall boundary */
171 static TUNABLE(bool, proc_ref_tracking_disabled, "-disable_procref_tracking", false);
172 #endif
173 
174 struct proclist allproc = LIST_HEAD_INITIALIZER(allproc);
175 struct proclist zombproc = LIST_HEAD_INITIALIZER(zombproc);
176 extern struct tty cons;
177 
178 extern int cs_debug;
179 
180 #if DEVELOPMENT || DEBUG
181 static TUNABLE(bool, syscallfilter_disable, "-disable_syscallfilter", false);
182 #endif // DEVELOPMENT || DEBUG
183 
184 #if DEBUG
185 #define __PROC_INTERNAL_DEBUG 1
186 #endif
187 #if CONFIG_COREDUMP
188 /* Name to give to core files */
189 #if defined(XNU_TARGET_OS_BRIDGE)
190 __XNU_PRIVATE_EXTERN char corefilename[MAXPATHLEN + 1] = {"/private/var/internal/%N.core"};
191 #elif defined(XNU_TARGET_OS_OSX)
192 __XNU_PRIVATE_EXTERN char corefilename[MAXPATHLEN + 1] = {"/cores/core.%P"};
193 #else
194 __XNU_PRIVATE_EXTERN char corefilename[MAXPATHLEN + 1] = {"/private/var/cores/%N.core"};
195 #endif
196 #endif
197 
198 #if PROC_REF_DEBUG
199 #include <kern/backtrace.h>
200 #endif
201 
202 static LCK_MTX_DECLARE_ATTR(proc_klist_mlock, &proc_mlock_grp, &proc_lck_attr);
203 
204 ZONE_DECLARE(pgrp_zone, "pgrp",
205     sizeof(struct pgrp), ZC_ZFREE_CLEARMEM);
206 ZONE_DECLARE(session_zone, "session",
207     sizeof(struct session), ZC_ZFREE_CLEARMEM);
208 static SECURITY_READ_ONLY_LATE(zone_t) proc_ro_zone;
209 ZONE_INIT(&proc_ro_zone, "proc_ro", sizeof(struct proc_ro),
210     ZC_READONLY | ZC_ZFREE_CLEARMEM, ZONE_ID_PROC_RO, NULL);
211 
212 typedef uint64_t unaligned_u64 __attribute__((aligned(1)));
213 
214 static void orphanpg(struct pgrp * pg);
215 void proc_name_kdp(proc_t t, char * buf, int size);
216 boolean_t proc_binary_uuid_kdp(task_t task, uuid_t uuid);
217 boolean_t current_thread_aborted(void);
218 int proc_threadname_kdp(void * uth, char * buf, size_t size);
219 void proc_starttime_kdp(void * p, unaligned_u64 *tv_sec, unaligned_u64 *tv_usec, unaligned_u64 *abstime);
220 void proc_archinfo_kdp(void* p, cpu_type_t* cputype, cpu_subtype_t* cpusubtype);
221 char * proc_name_address(void * p);
222 char * proc_longname_address(void *);
223 
224 static void pgrp_destroy(struct pgrp *pgrp);
225 static void pgrp_replace(proc_t p, struct pgrp *pgrp);
226 static int csops_internal(pid_t pid, int ops, user_addr_t uaddr, user_size_t usersize, user_addr_t uaddittoken);
227 static boolean_t proc_parent_is_currentproc(proc_t p);
228 
229 extern void task_filedesc_ast(task_t task, int current_size, int soft_limit, int hard_limit);
230 
231 struct fixjob_iterargs {
232 	struct pgrp * pg;
233 	struct session * mysession;
234 	int entering;
235 };
236 
237 int fixjob_callback(proc_t, void *);
238 
239 uint64_t
get_current_unique_pid(void)240 get_current_unique_pid(void)
241 {
242 	proc_t  p = current_proc();
243 
244 	if (p) {
245 		return proc_uniqueid(p);
246 	} else {
247 		return 0;
248 	}
249 }
250 
251 /*
252  * Initialize global process hashing structures.
253  */
254 static void
procinit(void)255 procinit(void)
256 {
257 	pidhashtbl = hashinit(maxproc / 4, M_PROC, &pidhash);
258 	pgrphashtbl = hashinit(maxproc / 4, M_PROC, &pgrphash);
259 	sesshashtbl = hashinit(maxproc / 4, M_PROC, &sesshash);
260 	uihashtbl = hashinit(maxproc / 16, M_PROC, &uihash);
261 }
262 STARTUP(EARLY_BOOT, STARTUP_RANK_FIRST, procinit);
263 
264 /*
265  * Change the count associated with number of processes
266  * a given user is using. This routine protects the uihash
267  * with the list lock
268  */
269 size_t
chgproccnt(uid_t uid,int diff)270 chgproccnt(uid_t uid, int diff)
271 {
272 	struct uidinfo *uip;
273 	struct uidinfo *newuip = NULL;
274 	struct uihashhead *uipp;
275 	size_t retval;
276 
277 again:
278 	proc_list_lock();
279 	uipp = UIHASH(uid);
280 	for (uip = uipp->lh_first; uip != 0; uip = uip->ui_hash.le_next) {
281 		if (uip->ui_uid == uid) {
282 			break;
283 		}
284 	}
285 	if (uip) {
286 		uip->ui_proccnt += diff;
287 		if (uip->ui_proccnt > 0) {
288 			retval = uip->ui_proccnt;
289 			proc_list_unlock();
290 			goto out;
291 		}
292 		LIST_REMOVE(uip, ui_hash);
293 		retval = 0;
294 		proc_list_unlock();
295 		kfree_type(struct uidinfo, uip);
296 		goto out;
297 	}
298 	if (diff <= 0) {
299 		if (diff == 0) {
300 			retval = 0;
301 			proc_list_unlock();
302 			goto out;
303 		}
304 		panic("chgproccnt: lost user");
305 	}
306 	if (newuip != NULL) {
307 		uip = newuip;
308 		newuip = NULL;
309 		LIST_INSERT_HEAD(uipp, uip, ui_hash);
310 		uip->ui_uid = uid;
311 		uip->ui_proccnt = diff;
312 		retval = diff;
313 		proc_list_unlock();
314 		goto out;
315 	}
316 	proc_list_unlock();
317 	newuip = kalloc_type(struct uidinfo, Z_WAITOK | Z_NOFAIL);
318 	goto again;
319 out:
320 	kfree_type(struct uidinfo, newuip);
321 	return retval;
322 }
323 
324 /*
325  * Is p an inferior of the current process?
326  */
327 int
inferior(proc_t p)328 inferior(proc_t p)
329 {
330 	int retval = 0;
331 
332 	proc_list_lock();
333 	for (; p != current_proc(); p = p->p_pptr) {
334 		if (proc_getpid(p) == 0) {
335 			goto out;
336 		}
337 	}
338 	retval = 1;
339 out:
340 	proc_list_unlock();
341 	return retval;
342 }
343 
344 /*
345  * Is p an inferior of t ?
346  */
347 int
isinferior(proc_t p,proc_t t)348 isinferior(proc_t p, proc_t t)
349 {
350 	int retval = 0;
351 	int nchecked = 0;
352 	proc_t start = p;
353 
354 	/* if p==t they are not inferior */
355 	if (p == t) {
356 		return 0;
357 	}
358 
359 	proc_list_lock();
360 	for (; p != t; p = p->p_pptr) {
361 		nchecked++;
362 
363 		/* Detect here if we're in a cycle */
364 		if ((proc_getpid(p) == 0) || (p->p_pptr == start) || (nchecked >= nprocs)) {
365 			goto out;
366 		}
367 	}
368 	retval = 1;
369 out:
370 	proc_list_unlock();
371 	return retval;
372 }
373 
374 int
proc_isinferior(int pid1,int pid2)375 proc_isinferior(int pid1, int pid2)
376 {
377 	proc_t p = PROC_NULL;
378 	proc_t t = PROC_NULL;
379 	int retval = 0;
380 
381 	if (((p = proc_find(pid1)) != (proc_t)0) && ((t = proc_find(pid2)) != (proc_t)0)) {
382 		retval = isinferior(p, t);
383 	}
384 
385 	if (p != PROC_NULL) {
386 		proc_rele(p);
387 	}
388 	if (t != PROC_NULL) {
389 		proc_rele(t);
390 	}
391 
392 	return retval;
393 }
394 
395 /*
396  * Returns process identity of a given process. Calling this function is not
397  * racy for a current process or if a reference to the process is held.
398  */
399 struct proc_ident
proc_ident(proc_t p)400 proc_ident(proc_t p)
401 {
402 	struct proc_ident ident = {
403 		.p_pid = proc_pid(p),
404 		.p_uniqueid = proc_uniqueid(p),
405 		.p_idversion = proc_pidversion(p),
406 	};
407 
408 	return ident;
409 }
410 
411 proc_t
proc_find_ident(struct proc_ident const * ident)412 proc_find_ident(struct proc_ident const *ident)
413 {
414 	proc_t proc = PROC_NULL;
415 
416 	proc = proc_find(ident->p_pid);
417 	if (proc == PROC_NULL) {
418 		return PROC_NULL;
419 	}
420 
421 	if (proc_uniqueid(proc) != ident->p_uniqueid ||
422 	    proc_pidversion(proc) != ident->p_idversion) {
423 		proc_rele(proc);
424 		return PROC_NULL;
425 	}
426 
427 	return proc;
428 }
429 
430 void
uthread_reset_proc_refcount(uthread_t uth)431 uthread_reset_proc_refcount(uthread_t uth)
432 {
433 	uth->uu_proc_refcount = 0;
434 
435 #if PROC_REF_DEBUG
436 	if (proc_ref_tracking_disabled) {
437 		return;
438 	}
439 
440 	uth->uu_proc_ref_info->upri_pindex = 0;
441 #endif
442 }
443 
444 #if PROC_REF_DEBUG
445 void
uthread_init_proc_refcount(uthread_t uth)446 uthread_init_proc_refcount(uthread_t uth)
447 {
448 	if (proc_ref_tracking_disabled) {
449 		return;
450 	}
451 
452 	uth->uu_proc_ref_info = kalloc_type(struct uthread_proc_ref_info,
453 	    Z_ZERO | Z_WAITOK | Z_NOFAIL);
454 }
455 
456 void
uthread_destroy_proc_refcount(uthread_t uth)457 uthread_destroy_proc_refcount(uthread_t uth)
458 {
459 	if (proc_ref_tracking_disabled) {
460 		return;
461 	}
462 
463 	kfree_type(struct uthread_proc_ref_info, uth->uu_proc_ref_info);
464 }
465 
466 void
uthread_assert_zero_proc_refcount(uthread_t uth)467 uthread_assert_zero_proc_refcount(uthread_t uth)
468 {
469 	if (proc_ref_tracking_disabled) {
470 		return;
471 	}
472 
473 	if (__improbable(uth->uu_proc_refcount != 0)) {
474 		panic("Unexpected non zero uu_proc_refcount = %d (%p)",
475 		    uth->uu_proc_refcount, uth);
476 	}
477 }
478 #endif
479 
480 bool
proc_list_exited(proc_t p)481 proc_list_exited(proc_t p)
482 {
483 	return os_ref_get_raw_mask(&p->p_refcount) & P_REF_DEAD;
484 }
485 
486 #if CONFIG_DEBUG_SYSCALL_REJECTION
487 uint64_t*
uthread_get_syscall_rejection_mask(void * uthread)488 uthread_get_syscall_rejection_mask(void *uthread)
489 {
490 	uthread_t uth = (uthread_t) uthread;
491 	return uth->syscall_rejection_mask;
492 }
493 #endif /* CONFIG_DEBUG_SYSCALL_REJECTION */
494 
495 static void
record_procref(proc_t p __unused,int count)496 record_procref(proc_t p __unused, int count)
497 {
498 	uthread_t uth;
499 
500 	uth = current_uthread();
501 	uth->uu_proc_refcount += count;
502 
503 #if PROC_REF_DEBUG
504 	if (proc_ref_tracking_disabled) {
505 		return;
506 	}
507 	struct uthread_proc_ref_info *upri = uth->uu_proc_ref_info;
508 
509 	if (upri->upri_pindex < NUM_PROC_REFS_TO_TRACK) {
510 		backtrace((uintptr_t *)&upri->upri_proc_pcs[upri->upri_pindex],
511 		    PROC_REF_STACK_DEPTH, NULL, NULL);
512 
513 		upri->upri_proc_ps[upri->upri_pindex] = p;
514 		upri->upri_pindex++;
515 	}
516 #endif
517 }
518 
519 /*!
520  * @function proc_ref_try_fast()
521  *
522  * @brief
523  * Tries to take a proc ref, unless it is in flux (being made, or dead).
524  *
525  * @returns
526  * - the new refcount value (including bits) on success,
527  * - 0 on failure.
528  */
529 static inline uint32_t
proc_ref_try_fast(proc_t p)530 proc_ref_try_fast(proc_t p)
531 {
532 	uint32_t bits;
533 
534 	proc_require(p, PROC_REQUIRE_ALLOW_KERNPROC);
535 
536 	bits = os_ref_retain_try_mask(&p->p_refcount, P_REF_BITS,
537 	    P_REF_NEW | P_REF_DEAD, NULL);
538 	if (bits) {
539 		record_procref(p, 1);
540 	}
541 	return bits;
542 }
543 
544 /*!
545  * @function proc_ref_wait()
546  *
547  * @brief
548  * Waits for the specified bits to clear, on the specified event.
549  */
550 __attribute__((noinline))
551 static void
proc_ref_wait(proc_t p,event_t event,proc_ref_bits_t mask,bool locked)552 proc_ref_wait(proc_t p, event_t event, proc_ref_bits_t mask, bool locked)
553 {
554 	assert_wait(event, THREAD_UNINT | THREAD_WAIT_NOREPORT);
555 
556 	if (os_ref_get_raw_mask(&p->p_refcount) & mask) {
557 		uthread_t uth = current_uthread();
558 
559 		if (locked) {
560 			proc_list_unlock();
561 		}
562 		uth->uu_wchan = event;
563 		uth->uu_wmesg = "proc_refwait";
564 		thread_block(THREAD_CONTINUE_NULL);
565 		uth->uu_wchan = NULL;
566 		uth->uu_wmesg = NULL;
567 		if (locked) {
568 			proc_list_lock();
569 		}
570 	} else {
571 		clear_wait(current_thread(), THREAD_AWAKENED);
572 	}
573 }
574 
575 /*!
576  * @function proc_ref_wait_for_exec()
577  *
578  * @brief
579  * Routine called by processes trying to acquire a ref while
580  * an exec is in flight.
581  *
582  * @discussion
583  * This function is called with a proc ref held on the proc,
584  * which will be given up until the @c P_REF_*_EXEC flags clear.
585  *
586  * @param p       the proc, the caller owns a proc ref
587  * @param bits    the result of @c proc_ref_try_fast() prior to calling this.
588  * @param locked  whether the caller holds the @c proc_list_lock().
589  */
590 __attribute__((noinline))
591 static proc_t
proc_ref_wait_for_exec(proc_t p,uint32_t bits,int locked)592 proc_ref_wait_for_exec(proc_t p, uint32_t bits, int locked)
593 {
594 	const proc_ref_bits_t mask = P_REF_WILL_EXEC | P_REF_IN_EXEC;
595 
596 	/*
597 	 * the proc is in the middle of exec,
598 	 * trade our ref for a "wait ref",
599 	 * and wait for the proc_refwake_did_exec() call.
600 	 *
601 	 * Note: it's very unlikely that we'd loop back into the wait,
602 	 *       it would only happen if the target proc would be
603 	 *       in exec again by the time we woke up.
604 	 */
605 	os_ref_retain_raw(&p->p_waitref, &p_refgrp);
606 
607 	do {
608 		proc_rele(p);
609 		proc_ref_wait(p, &p->p_waitref, mask, locked);
610 		bits = proc_ref_try_fast(p);
611 	} while (__improbable(bits & mask));
612 
613 	proc_wait_release(p);
614 
615 	return bits ? p : PROC_NULL;
616 }
617 
618 static inline bool
proc_ref_needs_wait_for_exec(uint32_t bits)619 proc_ref_needs_wait_for_exec(uint32_t bits)
620 {
621 	if (__probable((bits & (P_REF_WILL_EXEC | P_REF_IN_EXEC)) == 0)) {
622 		return false;
623 	}
624 
625 	if (bits & P_REF_IN_EXEC) {
626 		return true;
627 	}
628 
629 	/*
630 	 * procs can't have outstanding refs while execing.
631 	 *
632 	 * In order to achieve, that, proc_refdrain_will_exec()
633 	 * will drain outstanding references. It signals its intent
634 	 * with the P_REF_WILL_EXEC flag, and moves to P_REF_IN_EXEC
635 	 * when this is achieved.
636 	 *
637 	 * Most threads will block in proc_ref() when any of those
638 	 * flags is set. However, threads that already have
639 	 * an oustanding ref on this proc might want another
640 	 * before dropping them. To avoid deadlocks, we need
641 	 * to let threads with any oustanding reference take one
642 	 * when only P_REF_WILL_EXEC is set (which causes exec
643 	 * to be delayed).
644 	 *
645 	 * Note: the current thread will _always_ appear like it holds
646 	 *       one ref due to having taken one speculatively.
647 	 */
648 	assert(current_uthread()->uu_proc_refcount >= 1);
649 	return current_uthread()->uu_proc_refcount == 1;
650 }
651 
652 int
proc_rele(proc_t p)653 proc_rele(proc_t p)
654 {
655 	uint32_t o_bits, n_bits;
656 
657 	proc_require(p, PROC_REQUIRE_ALLOW_KERNPROC);
658 
659 	os_atomic_rmw_loop(&p->p_refcount, o_bits, n_bits, release, {
660 		n_bits = o_bits - (1u << P_REF_BITS);
661 		if ((n_bits >> P_REF_BITS) == 1) {
662 		        n_bits &= ~P_REF_DRAINING;
663 		}
664 	});
665 	record_procref(p, -1);
666 
667 	/*
668 	 * p might be freed after this point.
669 	 */
670 
671 	if (__improbable((o_bits & P_REF_DRAINING) && !(n_bits & P_REF_DRAINING))) {
672 		/*
673 		 * This wakeup can cause spurious ones,
674 		 * but proc_refdrain() can deal with those.
675 		 *
676 		 * Because the proc_zone memory is sequestered,
677 		 * this is safe to wakeup a possible "freed" address.
678 		 */
679 		wakeup(&p->p_refcount);
680 	}
681 	return 0;
682 }
683 
684 proc_t
proc_self(void)685 proc_self(void)
686 {
687 	proc_t p = current_proc();
688 
689 	/*
690 	 * Do not go through the logic of "wait for exec", it is meaningless.
691 	 * Only fail taking a ref for oneself if the proc is about to die.
692 	 */
693 	return proc_ref_try_fast(p) ? p : PROC_NULL;
694 }
695 
696 proc_t
proc_ref(proc_t p,int locked)697 proc_ref(proc_t p, int locked)
698 {
699 	uint32_t bits;
700 
701 	bits = proc_ref_try_fast(p);
702 	if (__improbable(!bits)) {
703 		return PROC_NULL;
704 	}
705 
706 	if (__improbable(proc_ref_needs_wait_for_exec(bits))) {
707 		return proc_ref_wait_for_exec(p, bits, locked);
708 	}
709 
710 	return p;
711 }
712 
713 static void
proc_free(void * _p)714 proc_free(void *_p)
715 {
716 	proc_t p = _p;
717 	proc_t pn = hazard_ptr_serialized_load(&p->p_hash);
718 
719 	if (pn) {
720 		/* release the reference taken in phash_remove_locked() */
721 		proc_wait_release(pn);
722 	}
723 	zfree(proc_zone, p);
724 }
725 
726 void
proc_wait_release(proc_t p)727 proc_wait_release(proc_t p)
728 {
729 	if (__probable(os_ref_release_raw(&p->p_waitref, &p_refgrp) == 0)) {
730 		hazard_retire(p, sizeof(*p), proc_free);
731 	}
732 }
733 
734 proc_t
proc_find_zombref(int pid)735 proc_find_zombref(int pid)
736 {
737 	proc_t p;
738 
739 	proc_list_lock();
740 
741 again:
742 	p = phash_find_locked(pid);
743 
744 	/* should we bail? */
745 	if ((p == PROC_NULL) || !proc_list_exited(p)) {
746 		proc_list_unlock();
747 		return PROC_NULL;
748 	}
749 
750 	/* If someone else is controlling the (unreaped) zombie - wait */
751 	if ((p->p_listflag & P_LIST_WAITING) != 0) {
752 		(void)msleep(&p->p_stat, &proc_list_mlock, PWAIT, "waitcoll", 0);
753 		goto again;
754 	}
755 	p->p_listflag |=  P_LIST_WAITING;
756 
757 	proc_list_unlock();
758 
759 	return p;
760 }
761 
762 void
proc_drop_zombref(proc_t p)763 proc_drop_zombref(proc_t p)
764 {
765 	proc_list_lock();
766 	if ((p->p_listflag & P_LIST_WAITING) == P_LIST_WAITING) {
767 		p->p_listflag &= ~P_LIST_WAITING;
768 		wakeup(&p->p_stat);
769 	}
770 	proc_list_unlock();
771 }
772 
773 
774 void
proc_refdrain(proc_t p)775 proc_refdrain(proc_t p)
776 {
777 	uint32_t bits = os_ref_get_raw_mask(&p->p_refcount);
778 
779 	assert(proc_list_exited(p));
780 
781 	while ((bits >> P_REF_BITS) > 1) {
782 		if (os_atomic_cmpxchgv(&p->p_refcount, bits,
783 		    bits | P_REF_DRAINING, &bits, relaxed)) {
784 			proc_ref_wait(p, &p->p_refcount, P_REF_DRAINING, false);
785 		}
786 	}
787 }
788 
789 proc_t
proc_refdrain_will_exec(proc_t p)790 proc_refdrain_will_exec(proc_t p)
791 {
792 	const proc_ref_bits_t will_exec_mask = P_REF_WILL_EXEC | P_REF_DRAINING;
793 
794 	/*
795 	 * All the calls to proc_ref will wait
796 	 * for the flag to get cleared before returning a ref.
797 	 *
798 	 * (except for the case documented in proc_ref_needs_wait_for_exec()).
799 	 */
800 
801 	if (p == initproc) {
802 		/* Do not wait in ref drain for launchd exec */
803 		os_atomic_or(&p->p_refcount, P_REF_IN_EXEC, relaxed);
804 	} else {
805 		for (;;) {
806 			uint32_t o_ref, n_ref;
807 
808 			os_atomic_rmw_loop(&p->p_refcount, o_ref, n_ref, relaxed, {
809 				if ((o_ref >> P_REF_BITS) == 1) {
810 				        /*
811 				         * We drained successfully,
812 				         * move on to P_REF_IN_EXEC
813 				         */
814 				        n_ref = o_ref & ~will_exec_mask;
815 				        n_ref |= P_REF_IN_EXEC;
816 				} else {
817 				        /*
818 				         * Outstanding refs exit,
819 				         * mark our desire to stall
820 				         * proc_ref() callers with
821 				         * P_REF_WILL_EXEC.
822 				         */
823 				        n_ref = o_ref | will_exec_mask;
824 				}
825 			});
826 
827 			if (n_ref & P_REF_IN_EXEC) {
828 				break;
829 			}
830 
831 			proc_ref_wait(p, &p->p_refcount, P_REF_DRAINING, false);
832 		}
833 	}
834 
835 	/* Return a ref to the caller */
836 	os_ref_retain_mask(&p->p_refcount, P_REF_BITS, NULL);
837 	record_procref(p, 1);
838 
839 	return p;
840 }
841 
842 void
proc_refwake_did_exec(proc_t p)843 proc_refwake_did_exec(proc_t p)
844 {
845 	os_atomic_andnot(&p->p_refcount, P_REF_IN_EXEC, release);
846 	wakeup(&p->p_waitref);
847 }
848 
849 proc_t
proc_parentholdref(proc_t p)850 proc_parentholdref(proc_t p)
851 {
852 	proc_t parent = PROC_NULL;
853 	proc_t pp;
854 	int loopcnt = 0;
855 
856 
857 	proc_list_lock();
858 loop:
859 	pp = p->p_pptr;
860 	if ((pp == PROC_NULL) || (pp->p_stat == SZOMB) || ((pp->p_listflag & (P_LIST_CHILDDRSTART | P_LIST_CHILDDRAINED)) == (P_LIST_CHILDDRSTART | P_LIST_CHILDDRAINED))) {
861 		parent = PROC_NULL;
862 		goto out;
863 	}
864 
865 	if ((pp->p_listflag & (P_LIST_CHILDDRSTART | P_LIST_CHILDDRAINED)) == P_LIST_CHILDDRSTART) {
866 		pp->p_listflag |= P_LIST_CHILDDRWAIT;
867 		msleep(&pp->p_childrencnt, &proc_list_mlock, 0, "proc_parent", 0);
868 		loopcnt++;
869 		if (loopcnt == 5) {
870 			parent = PROC_NULL;
871 			goto out;
872 		}
873 		goto loop;
874 	}
875 
876 	if ((pp->p_listflag & (P_LIST_CHILDDRSTART | P_LIST_CHILDDRAINED)) == 0) {
877 		pp->p_parentref++;
878 		parent = pp;
879 		goto out;
880 	}
881 
882 out:
883 	proc_list_unlock();
884 	return parent;
885 }
886 int
proc_parentdropref(proc_t p,int listlocked)887 proc_parentdropref(proc_t p, int listlocked)
888 {
889 	if (listlocked == 0) {
890 		proc_list_lock();
891 	}
892 
893 	if (p->p_parentref > 0) {
894 		p->p_parentref--;
895 		if ((p->p_parentref == 0) && ((p->p_listflag & P_LIST_PARENTREFWAIT) == P_LIST_PARENTREFWAIT)) {
896 			p->p_listflag &= ~P_LIST_PARENTREFWAIT;
897 			wakeup(&p->p_parentref);
898 		}
899 	} else {
900 		panic("proc_parentdropref  -ve ref");
901 	}
902 	if (listlocked == 0) {
903 		proc_list_unlock();
904 	}
905 
906 	return 0;
907 }
908 
909 void
proc_childdrainstart(proc_t p)910 proc_childdrainstart(proc_t p)
911 {
912 #if __PROC_INTERNAL_DEBUG
913 	if ((p->p_listflag & P_LIST_CHILDDRSTART) == P_LIST_CHILDDRSTART) {
914 		panic("proc_childdrainstart: childdrain already started");
915 	}
916 #endif
917 	p->p_listflag |= P_LIST_CHILDDRSTART;
918 	/* wait for all that hold parentrefs to drop */
919 	while (p->p_parentref > 0) {
920 		p->p_listflag |= P_LIST_PARENTREFWAIT;
921 		msleep(&p->p_parentref, &proc_list_mlock, 0, "proc_childdrainstart", 0);
922 	}
923 }
924 
925 
926 void
proc_childdrainend(proc_t p)927 proc_childdrainend(proc_t p)
928 {
929 #if __PROC_INTERNAL_DEBUG
930 	if (p->p_childrencnt > 0) {
931 		panic("exiting: children stil hanging around");
932 	}
933 #endif
934 	p->p_listflag |= P_LIST_CHILDDRAINED;
935 	if ((p->p_listflag & (P_LIST_CHILDLKWAIT | P_LIST_CHILDDRWAIT)) != 0) {
936 		p->p_listflag &= ~(P_LIST_CHILDLKWAIT | P_LIST_CHILDDRWAIT);
937 		wakeup(&p->p_childrencnt);
938 	}
939 }
940 
941 void
proc_checkdeadrefs(__unused proc_t p)942 proc_checkdeadrefs(__unused proc_t p)
943 {
944 	uint32_t bits;
945 
946 	bits = os_ref_release_raw_mask(&p->p_refcount, P_REF_BITS, NULL);
947 	if (bits != P_REF_DEAD) {
948 		panic("proc being freed and unexpected refcount %p:%d:0x%x", p,
949 		    bits >> P_REF_BITS, bits & P_REF_MASK);
950 	}
951 #if __PROC_INTERNAL_DEBUG
952 	if (p->p_childrencnt != 0) {
953 		panic("proc being freed and pending children cnt %p:%d", p, p->p_childrencnt);
954 	}
955 	if (p->p_parentref != 0) {
956 		panic("proc being freed and pending parentrefs %p:%d", p, p->p_parentref);
957 	}
958 #endif
959 }
960 
961 
962 __attribute__((always_inline, visibility("hidden")))
963 void
proc_require(proc_t proc,proc_require_flags_t flags)964 proc_require(proc_t proc, proc_require_flags_t flags)
965 {
966 	if ((flags & PROC_REQUIRE_ALLOW_NULL) && proc == PROC_NULL) {
967 		return;
968 	}
969 	if ((flags & PROC_REQUIRE_ALLOW_KERNPROC) && proc == &proc0) {
970 		return;
971 	}
972 	zone_id_require(ZONE_ID_PROC, sizeof(struct proc), proc);
973 }
974 
975 pid_t
proc_getpid(proc_t p)976 proc_getpid(proc_t p)
977 {
978 	if (p == &proc0) {
979 		return 0;
980 	}
981 
982 	return p->p_pid;
983 }
984 
985 int
proc_pid(proc_t p)986 proc_pid(proc_t p)
987 {
988 	if (p != NULL) {
989 		proc_require(p, PROC_REQUIRE_ALLOW_KERNPROC);
990 		return proc_getpid(p);
991 	}
992 	return -1;
993 }
994 
995 int
proc_ppid(proc_t p)996 proc_ppid(proc_t p)
997 {
998 	if (p != NULL) {
999 		proc_require(p, PROC_REQUIRE_ALLOW_KERNPROC);
1000 		return p->p_ppid;
1001 	}
1002 	return -1;
1003 }
1004 
1005 int
proc_original_ppid(proc_t p)1006 proc_original_ppid(proc_t p)
1007 {
1008 	if (p != NULL) {
1009 		proc_require(p, PROC_REQUIRE_ALLOW_KERNPROC);
1010 		return p->p_original_ppid;
1011 	}
1012 	return -1;
1013 }
1014 
1015 int
proc_starttime(proc_t p,struct timeval * tv)1016 proc_starttime(proc_t p, struct timeval *tv)
1017 {
1018 	if (p != NULL && tv != NULL) {
1019 		tv->tv_sec = p->p_start.tv_sec;
1020 		tv->tv_usec = p->p_start.tv_usec;
1021 		return 0;
1022 	}
1023 	return EINVAL;
1024 }
1025 
1026 int
proc_selfpid(void)1027 proc_selfpid(void)
1028 {
1029 	return proc_getpid(current_proc());
1030 }
1031 
1032 int
proc_selfppid(void)1033 proc_selfppid(void)
1034 {
1035 	return current_proc()->p_ppid;
1036 }
1037 
1038 uint64_t
proc_selfcsflags(void)1039 proc_selfcsflags(void)
1040 {
1041 	return proc_getcsflags(current_proc());
1042 }
1043 
1044 int
proc_csflags(proc_t p,uint64_t * flags)1045 proc_csflags(proc_t p, uint64_t *flags)
1046 {
1047 	if (p && flags) {
1048 		proc_require(p, PROC_REQUIRE_ALLOW_KERNPROC);
1049 		*flags = proc_getcsflags(p);
1050 		return 0;
1051 	}
1052 	return EINVAL;
1053 }
1054 
1055 boolean_t
proc_is_simulated(const proc_t p)1056 proc_is_simulated(const proc_t p)
1057 {
1058 #ifdef XNU_TARGET_OS_OSX
1059 	if (p != NULL) {
1060 		switch (proc_platform(p)) {
1061 		case PLATFORM_IOSSIMULATOR:
1062 		case PLATFORM_TVOSSIMULATOR:
1063 		case PLATFORM_WATCHOSSIMULATOR:
1064 			return TRUE;
1065 		default:
1066 			return FALSE;
1067 		}
1068 	}
1069 #else /* !XNU_TARGET_OS_OSX */
1070 	(void)p;
1071 #endif
1072 	return FALSE;
1073 }
1074 
1075 uint32_t
proc_platform(const proc_t p)1076 proc_platform(const proc_t p)
1077 {
1078 	if (p != NULL) {
1079 		return proc_get_ro(p)->p_platform_data.p_platform;
1080 	}
1081 	return (uint32_t)-1;
1082 }
1083 
1084 uint32_t
proc_min_sdk(proc_t p)1085 proc_min_sdk(proc_t p)
1086 {
1087 	if (p != NULL) {
1088 		return proc_get_ro(p)->p_platform_data.p_min_sdk;
1089 	}
1090 	return (uint32_t)-1;
1091 }
1092 
1093 uint32_t
proc_sdk(proc_t p)1094 proc_sdk(proc_t p)
1095 {
1096 	if (p != NULL) {
1097 		return proc_get_ro(p)->p_platform_data.p_sdk;
1098 	}
1099 	return (uint32_t)-1;
1100 }
1101 
1102 void
proc_setplatformdata(proc_t p,uint32_t platform,uint32_t min_sdk,uint32_t sdk)1103 proc_setplatformdata(proc_t p, uint32_t platform, uint32_t min_sdk, uint32_t sdk)
1104 {
1105 	proc_ro_t ro;
1106 	struct proc_platform_ro_data platform_data;
1107 
1108 	ro = proc_get_ro(p);
1109 	platform_data = ro->p_platform_data;
1110 	platform_data.p_platform = platform;
1111 	platform_data.p_min_sdk = min_sdk;
1112 	platform_data.p_sdk = sdk;
1113 
1114 	zalloc_ro_update_field(ZONE_ID_PROC_RO, ro, p_platform_data, &platform_data);
1115 }
1116 
1117 #if CONFIG_DTRACE
1118 int
dtrace_proc_selfpid(void)1119 dtrace_proc_selfpid(void)
1120 {
1121 	return proc_selfpid();
1122 }
1123 
1124 int
dtrace_proc_selfppid(void)1125 dtrace_proc_selfppid(void)
1126 {
1127 	return proc_selfppid();
1128 }
1129 
1130 uid_t
dtrace_proc_selfruid(void)1131 dtrace_proc_selfruid(void)
1132 {
1133 	return current_proc()->p_ruid;
1134 }
1135 #endif /* CONFIG_DTRACE */
1136 
1137 /*!
1138  * @function proc_parent()
1139  *
1140  * @brief
1141  * Returns a ref on the parent of @c p.
1142  *
1143  * @discussion
1144  * Returns a reference on the parent, or @c PROC_NULL
1145  * if both @c p and its parent are zombies.
1146  *
1147  * If the parent is currently dying, then this function waits
1148  * for the situation to be resolved.
1149  *
1150  * This function never returns @c PROC_NULL if @c p isn't
1151  * a zombie (@c p_stat is @c SZOMB) yet.
1152  */
1153 proc_t
proc_parent(proc_t p)1154 proc_parent(proc_t p)
1155 {
1156 	proc_t parent;
1157 	proc_t pp;
1158 
1159 	proc_list_lock();
1160 loop:
1161 	pp = p->p_pptr;
1162 	parent = proc_ref(pp, true);
1163 	if (parent == PROC_NULL && ((pp->p_listflag & P_LIST_CHILDDRAINED) == 0)) {
1164 		/*
1165 		 * If we can't get a reference on the parent,
1166 		 * wait for all children to have been reparented.
1167 		 */
1168 		pp->p_listflag |= P_LIST_CHILDLKWAIT;
1169 		msleep(&pp->p_childrencnt, &proc_list_mlock, 0, "proc_parent", 0);
1170 		goto loop;
1171 	}
1172 	proc_list_unlock();
1173 	return parent;
1174 }
1175 
1176 static boolean_t
proc_parent_is_currentproc(proc_t p)1177 proc_parent_is_currentproc(proc_t p)
1178 {
1179 	boolean_t ret = FALSE;
1180 
1181 	proc_list_lock();
1182 	if (p->p_pptr == current_proc()) {
1183 		ret = TRUE;
1184 	}
1185 
1186 	proc_list_unlock();
1187 	return ret;
1188 }
1189 
1190 void
proc_name(int pid,char * buf,int size)1191 proc_name(int pid, char * buf, int size)
1192 {
1193 	proc_t p;
1194 
1195 	if (size <= 0) {
1196 		return;
1197 	}
1198 
1199 	bzero(buf, size);
1200 
1201 	if ((p = proc_find(pid)) != PROC_NULL) {
1202 		strlcpy(buf, &p->p_comm[0], size);
1203 		proc_rele(p);
1204 	}
1205 }
1206 
1207 void
proc_name_kdp(proc_t p,char * buf,int size)1208 proc_name_kdp(proc_t p, char * buf, int size)
1209 {
1210 	if (p == PROC_NULL) {
1211 		return;
1212 	}
1213 
1214 	if ((size_t)size > sizeof(p->p_comm)) {
1215 		strlcpy(buf, &p->p_name[0], MIN((int)sizeof(p->p_name), size));
1216 	} else {
1217 		strlcpy(buf, &p->p_comm[0], MIN((int)sizeof(p->p_comm), size));
1218 	}
1219 }
1220 
1221 boolean_t
proc_binary_uuid_kdp(task_t task,uuid_t uuid)1222 proc_binary_uuid_kdp(task_t task, uuid_t uuid)
1223 {
1224 	proc_t p = get_bsdtask_info(task);
1225 	if (p == PROC_NULL) {
1226 		return FALSE;
1227 	}
1228 
1229 	proc_getexecutableuuid(p, uuid, sizeof(uuid_t));
1230 
1231 	return TRUE;
1232 }
1233 
1234 int
proc_threadname_kdp(void * uth,char * buf,size_t size)1235 proc_threadname_kdp(void * uth, char * buf, size_t size)
1236 {
1237 	if (size < MAXTHREADNAMESIZE) {
1238 		/* this is really just a protective measure for the future in
1239 		 * case the thread name size in stackshot gets out of sync with
1240 		 * the BSD max thread name size. Note that bsd_getthreadname
1241 		 * doesn't take input buffer size into account. */
1242 		return -1;
1243 	}
1244 
1245 	if (uth != NULL) {
1246 		bsd_getthreadname(uth, buf);
1247 	}
1248 	return 0;
1249 }
1250 
1251 
1252 /* note that this function is generally going to be called from stackshot,
1253  * and the arguments will be coming from a struct which is declared packed
1254  * thus the input arguments will in general be unaligned. We have to handle
1255  * that here. */
1256 void
proc_starttime_kdp(void * p,unaligned_u64 * tv_sec,unaligned_u64 * tv_usec,unaligned_u64 * abstime)1257 proc_starttime_kdp(void *p, unaligned_u64 *tv_sec, unaligned_u64 *tv_usec, unaligned_u64 *abstime)
1258 {
1259 	proc_t pp = (proc_t)p;
1260 	if (pp != PROC_NULL) {
1261 		if (tv_sec != NULL) {
1262 			*tv_sec = pp->p_start.tv_sec;
1263 		}
1264 		if (tv_usec != NULL) {
1265 			*tv_usec = pp->p_start.tv_usec;
1266 		}
1267 		if (abstime != NULL) {
1268 			if (pp->p_stats != NULL) {
1269 				*abstime = pp->p_stats->ps_start;
1270 			} else {
1271 				*abstime = 0;
1272 			}
1273 		}
1274 	}
1275 }
1276 
1277 void
proc_archinfo_kdp(void * p,cpu_type_t * cputype,cpu_subtype_t * cpusubtype)1278 proc_archinfo_kdp(void* p, cpu_type_t* cputype, cpu_subtype_t* cpusubtype)
1279 {
1280 	proc_t pp = (proc_t)p;
1281 	if (pp != PROC_NULL) {
1282 		*cputype = pp->p_cputype;
1283 		*cpusubtype = pp->p_cpusubtype;
1284 	}
1285 }
1286 
1287 char *
proc_name_address(void * p)1288 proc_name_address(void *p)
1289 {
1290 	return &((proc_t)p)->p_comm[0];
1291 }
1292 
1293 char *
proc_longname_address(void * p)1294 proc_longname_address(void *p)
1295 {
1296 	return &((proc_t)p)->p_name[0];
1297 }
1298 
1299 char *
proc_best_name(proc_t p)1300 proc_best_name(proc_t p)
1301 {
1302 	if (p->p_name[0] != '\0') {
1303 		return &p->p_name[0];
1304 	}
1305 	return &p->p_comm[0];
1306 }
1307 
1308 void
proc_selfname(char * buf,int size)1309 proc_selfname(char * buf, int  size)
1310 {
1311 	proc_t p;
1312 
1313 	if ((p = current_proc()) != (proc_t)0) {
1314 		strlcpy(buf, &p->p_name[0], size);
1315 	}
1316 }
1317 
1318 void
proc_signal(int pid,int signum)1319 proc_signal(int pid, int signum)
1320 {
1321 	proc_t p;
1322 
1323 	if ((p = proc_find(pid)) != PROC_NULL) {
1324 		psignal(p, signum);
1325 		proc_rele(p);
1326 	}
1327 }
1328 
1329 int
proc_issignal(int pid,sigset_t mask)1330 proc_issignal(int pid, sigset_t mask)
1331 {
1332 	proc_t p;
1333 	int error = 0;
1334 
1335 	if ((p = proc_find(pid)) != PROC_NULL) {
1336 		error = proc_pendingsignals(p, mask);
1337 		proc_rele(p);
1338 	}
1339 
1340 	return error;
1341 }
1342 
1343 int
proc_noremotehang(proc_t p)1344 proc_noremotehang(proc_t p)
1345 {
1346 	int retval = 0;
1347 
1348 	if (p) {
1349 		retval = p->p_flag & P_NOREMOTEHANG;
1350 	}
1351 	return retval? 1: 0;
1352 }
1353 
1354 int
proc_exiting(proc_t p)1355 proc_exiting(proc_t p)
1356 {
1357 	int retval = 0;
1358 
1359 	if (p) {
1360 		retval = p->p_lflag & P_LEXIT;
1361 	}
1362 	return retval? 1: 0;
1363 }
1364 
1365 int
proc_in_teardown(proc_t p)1366 proc_in_teardown(proc_t p)
1367 {
1368 	int retval = 0;
1369 
1370 	if (p) {
1371 		retval = p->p_lflag & P_LPEXIT;
1372 	}
1373 	return retval? 1: 0;
1374 }
1375 
1376 int
proc_lvfork(proc_t p __unused)1377 proc_lvfork(proc_t p __unused)
1378 {
1379 	return 0;
1380 }
1381 
1382 int
proc_increment_ru_oublock(proc_t p,long * origvalp)1383 proc_increment_ru_oublock(proc_t p, long *origvalp)
1384 {
1385 	long origval;
1386 
1387 	if (p && p->p_stats) {
1388 		origval = OSIncrementAtomicLong(&p->p_stats->p_ru.ru_oublock);
1389 		if (origvalp) {
1390 			*origvalp = origval;
1391 		}
1392 		return 0;
1393 	}
1394 
1395 	return EINVAL;
1396 }
1397 
1398 int
proc_isabortedsignal(proc_t p)1399 proc_isabortedsignal(proc_t p)
1400 {
1401 	if ((p != kernproc) && current_thread_aborted() &&
1402 	    (!(p->p_acflag & AXSIG) || (p->exit_thread != current_thread()) ||
1403 	    (p->p_sigacts.ps_sig < 1) || (p->p_sigacts.ps_sig >= NSIG) ||
1404 	    !hassigprop(p->p_sigacts.ps_sig, SA_CORE))) {
1405 		return 1;
1406 	}
1407 
1408 	return 0;
1409 }
1410 
1411 int
proc_forcequota(proc_t p)1412 proc_forcequota(proc_t p)
1413 {
1414 	int retval = 0;
1415 
1416 	if (p) {
1417 		retval = p->p_flag & P_FORCEQUOTA;
1418 	}
1419 	return retval? 1: 0;
1420 }
1421 
1422 int
proc_suser(proc_t p)1423 proc_suser(proc_t p)
1424 {
1425 	kauth_cred_t my_cred;
1426 	int error;
1427 
1428 	my_cred = kauth_cred_proc_ref(p);
1429 	error = suser(my_cred, &p->p_acflag);
1430 	kauth_cred_unref(&my_cred);
1431 	return error;
1432 }
1433 
1434 task_t
proc_task(proc_t proc)1435 proc_task(proc_t proc)
1436 {
1437 	return (task_t)proc->task;
1438 }
1439 
1440 void
proc_set_task(proc_t proc,task_t task)1441 proc_set_task(proc_t proc, task_t task)
1442 {
1443 	proc->task = task;
1444 }
1445 
1446 /*
1447  * Obtain the first thread in a process
1448  *
1449  * XXX This is a bad thing to do; it exists predominantly to support the
1450  * XXX use of proc_t's in places that should really be using
1451  * XXX thread_t's instead.  This maintains historical behaviour, but really
1452  * XXX needs an audit of the context (proxy vs. not) to clean up.
1453  */
1454 thread_t
proc_thread(proc_t proc)1455 proc_thread(proc_t proc)
1456 {
1457 	LCK_MTX_ASSERT(&proc->p_mlock, LCK_MTX_ASSERT_OWNED);
1458 
1459 	uthread_t uth = TAILQ_FIRST(&proc->p_uthlist);
1460 
1461 	if (uth != NULL) {
1462 		return get_machthread(uth);
1463 	}
1464 
1465 	return NULL;
1466 }
1467 
1468 kauth_cred_t
proc_ucred(proc_t p)1469 proc_ucred(proc_t p)
1470 {
1471 	return kauth_cred_require(proc_get_ro(p)->p_ucred);
1472 }
1473 
1474 struct uthread *
current_uthread(void)1475 current_uthread(void)
1476 {
1477 	return get_bsdthread_info(current_thread());
1478 }
1479 
1480 
1481 int
proc_is64bit(proc_t p)1482 proc_is64bit(proc_t p)
1483 {
1484 	return IS_64BIT_PROCESS(p);
1485 }
1486 
1487 int
proc_is64bit_data(proc_t p)1488 proc_is64bit_data(proc_t p)
1489 {
1490 	assert(p->task);
1491 	return (int)task_get_64bit_data(p->task);
1492 }
1493 
1494 int
proc_isinitproc(proc_t p)1495 proc_isinitproc(proc_t p)
1496 {
1497 	if (initproc == NULL) {
1498 		return 0;
1499 	}
1500 	return p == initproc;
1501 }
1502 
1503 int
proc_pidversion(proc_t p)1504 proc_pidversion(proc_t p)
1505 {
1506 	return proc_get_ro(p)->p_idversion;
1507 }
1508 
1509 void
proc_setpidversion(proc_t p,int idversion)1510 proc_setpidversion(proc_t p, int idversion)
1511 {
1512 	zalloc_ro_update_field(ZONE_ID_PROC_RO, proc_get_ro(p), p_idversion,
1513 	    &idversion);
1514 }
1515 
1516 uint32_t
proc_persona_id(proc_t p)1517 proc_persona_id(proc_t p)
1518 {
1519 	return (uint32_t)persona_id_from_proc(p);
1520 }
1521 
1522 uint32_t
proc_getuid(proc_t p)1523 proc_getuid(proc_t p)
1524 {
1525 	return p->p_uid;
1526 }
1527 
1528 uint32_t
proc_getgid(proc_t p)1529 proc_getgid(proc_t p)
1530 {
1531 	return p->p_gid;
1532 }
1533 
1534 uint64_t
proc_uniqueid(proc_t p)1535 proc_uniqueid(proc_t p)
1536 {
1537 	if (p == &proc0) {
1538 		return 0;
1539 	}
1540 
1541 	return proc_get_ro(p)->p_uniqueid;
1542 }
1543 
1544 uint64_t proc_uniqueid_task(void *p_arg, void *t);
1545 /*
1546  * During exec, two tasks point at the proc.  This function is used
1547  * to gives tasks a unique ID; we make the matching task have the
1548  * proc's uniqueid, and any other task gets the high-bit flipped.
1549  * (We need to try to avoid returning UINT64_MAX, which is the
1550  * which is the uniqueid of a task without a proc. (e.g. while exiting))
1551  *
1552  * Only used by get_task_uniqueid(); do not add additional callers.
1553  */
1554 uint64_t
proc_uniqueid_task(void * p_arg,void * t)1555 proc_uniqueid_task(void *p_arg, void *t)
1556 {
1557 	proc_t p = p_arg;
1558 	uint64_t uniqueid = proc_uniqueid(p);
1559 	return uniqueid ^ (__probable(t == (void *)p->task) ? 0 : (1ull << 63));
1560 }
1561 
1562 uint64_t
proc_puniqueid(proc_t p)1563 proc_puniqueid(proc_t p)
1564 {
1565 	return p->p_puniqueid;
1566 }
1567 
1568 void
proc_coalitionids(__unused proc_t p,__unused uint64_t ids[COALITION_NUM_TYPES])1569 proc_coalitionids(__unused proc_t p, __unused uint64_t ids[COALITION_NUM_TYPES])
1570 {
1571 #if CONFIG_COALITIONS
1572 	task_coalition_ids(p->task, ids);
1573 #else
1574 	memset(ids, 0, sizeof(uint64_t[COALITION_NUM_TYPES]));
1575 #endif
1576 	return;
1577 }
1578 
1579 uint64_t
proc_was_throttled(proc_t p)1580 proc_was_throttled(proc_t p)
1581 {
1582 	return p->was_throttled;
1583 }
1584 
1585 uint64_t
proc_did_throttle(proc_t p)1586 proc_did_throttle(proc_t p)
1587 {
1588 	return p->did_throttle;
1589 }
1590 
1591 int
proc_getcdhash(proc_t p,unsigned char * cdhash)1592 proc_getcdhash(proc_t p, unsigned char *cdhash)
1593 {
1594 	return vn_getcdhash(p->p_textvp, p->p_textoff, cdhash);
1595 }
1596 
1597 uint64_t
proc_getcsflags(proc_t p)1598 proc_getcsflags(proc_t p)
1599 {
1600 	return proc_get_ro(p)->p_csflags;
1601 }
1602 
1603 void
proc_csflags_update(proc_t p,uint64_t flags)1604 proc_csflags_update(proc_t p, uint64_t flags)
1605 {
1606 	uint32_t csflags = (uint32_t)flags;
1607 
1608 	if (p != kernproc) {
1609 		zalloc_ro_update_field(ZONE_ID_PROC_RO, proc_get_ro(p),
1610 		    p_csflags, &csflags);
1611 	}
1612 }
1613 
1614 void
proc_csflags_set(proc_t p,uint64_t flags)1615 proc_csflags_set(proc_t p, uint64_t flags)
1616 {
1617 	proc_csflags_update(p, proc_getcsflags(p) | (uint32_t)flags);
1618 }
1619 
1620 void
proc_csflags_clear(proc_t p,uint64_t flags)1621 proc_csflags_clear(proc_t p, uint64_t flags)
1622 {
1623 	proc_csflags_update(p, proc_getcsflags(p) & ~(uint32_t)flags);
1624 }
1625 
1626 uint8_t *
proc_syscall_filter_mask(proc_t p)1627 proc_syscall_filter_mask(proc_t p)
1628 {
1629 	return proc_get_ro(p)->syscall_filter_mask;
1630 }
1631 
1632 void
proc_syscall_filter_mask_set(proc_t p,uint8_t * mask)1633 proc_syscall_filter_mask_set(proc_t p, uint8_t *mask)
1634 {
1635 	zalloc_ro_update_field(ZONE_ID_PROC_RO, proc_get_ro(p),
1636 	    syscall_filter_mask, &mask);
1637 }
1638 
1639 int
proc_exitstatus(proc_t p)1640 proc_exitstatus(proc_t p)
1641 {
1642 	return p->p_xstat & 0xffff;
1643 }
1644 
1645 void
proc_setexecutableuuid(proc_t p,const unsigned char * uuid)1646 proc_setexecutableuuid(proc_t p, const unsigned char *uuid)
1647 {
1648 	memcpy(p->p_uuid, uuid, sizeof(p->p_uuid));
1649 }
1650 
1651 const unsigned char *
proc_executableuuid_addr(proc_t p)1652 proc_executableuuid_addr(proc_t p)
1653 {
1654 	return &p->p_uuid[0];
1655 }
1656 
1657 void
proc_getexecutableuuid(proc_t p,unsigned char * uuidbuf,unsigned long size)1658 proc_getexecutableuuid(proc_t p, unsigned char *uuidbuf, unsigned long size)
1659 {
1660 	if (size >= sizeof(uuid_t)) {
1661 		memcpy(uuidbuf, proc_executableuuid_addr(p), sizeof(uuid_t));
1662 	}
1663 }
1664 
1665 void
proc_set_ucred(proc_t p,kauth_cred_t cred)1666 proc_set_ucred(proc_t p, kauth_cred_t cred)
1667 {
1668 	kauth_cred_t my_cred = proc_ucred(p);
1669 
1670 	/* update the field first so the proc never points to a freed cred. */
1671 	zalloc_ro_update_field(ZONE_ID_PROC_RO, proc_get_ro(p), p_ucred, &cred);
1672 
1673 	kauth_cred_set(&my_cred, cred);
1674 }
1675 
1676 bool
1677 proc_update_label(proc_t p, bool setugid,
1678     kauth_cred_t (^update_cred)(kauth_cred_t))
1679 {
1680 	kauth_cred_t cur_cred;
1681 	kauth_cred_t new_cred;
1682 	bool changed = false;
1683 
1684 	cur_cred = kauth_cred_proc_ref(p);
1685 retry:
1686 	new_cred = update_cred(cur_cred);
1687 	if (new_cred != cur_cred) {
1688 		proc_ucred_lock(p);
1689 
1690 		/* Compare again under the lock. */
1691 		if (__improbable(proc_ucred(p) != cur_cred)) {
1692 			proc_ucred_unlock(p);
1693 			kauth_cred_unref(&new_cred);
1694 			cur_cred = kauth_cred_proc_ref(p);
1695 			goto retry;
1696 		}
1697 
1698 		proc_set_ucred(p, new_cred);
1699 		proc_update_creds_onproc(p);
1700 		proc_ucred_unlock(p);
1701 
1702 		if (setugid) {
1703 			OSBitOrAtomic(P_SUGID, &p->p_flag);
1704 			set_security_token(p);
1705 		}
1706 
1707 		changed = true;
1708 	}
1709 
1710 	kauth_cred_unref(&new_cred);
1711 	return changed;
1712 }
1713 
1714 /* Return vnode for executable with an iocount. Must be released with vnode_put() */
1715 vnode_t
proc_getexecutablevnode(proc_t p)1716 proc_getexecutablevnode(proc_t p)
1717 {
1718 	vnode_t tvp  = p->p_textvp;
1719 
1720 	if (tvp != NULLVP) {
1721 		if (vnode_getwithref(tvp) == 0) {
1722 			return tvp;
1723 		}
1724 	}
1725 
1726 	return NULLVP;
1727 }
1728 
1729 int
proc_gettty(proc_t p,vnode_t * vp)1730 proc_gettty(proc_t p, vnode_t *vp)
1731 {
1732 	struct session *procsp;
1733 	struct pgrp *pg;
1734 	int err = EINVAL;
1735 
1736 	if (!p || !vp) {
1737 		return EINVAL;
1738 	}
1739 
1740 	if ((pg = proc_pgrp(p, &procsp)) != PGRP_NULL) {
1741 		session_lock(procsp);
1742 		vnode_t ttyvp = procsp->s_ttyvp;
1743 		int ttyvid = procsp->s_ttyvid;
1744 		session_unlock(procsp);
1745 
1746 		if (ttyvp) {
1747 			if (vnode_getwithvid(ttyvp, ttyvid) == 0) {
1748 				*vp = ttyvp;
1749 				err = 0;
1750 			}
1751 		} else {
1752 			err = ENOENT;
1753 		}
1754 
1755 		pgrp_rele(pg);
1756 	}
1757 
1758 	return err;
1759 }
1760 
1761 int
proc_gettty_dev(proc_t p,dev_t * devp)1762 proc_gettty_dev(proc_t p, dev_t *devp)
1763 {
1764 	struct pgrp *pg;
1765 	dev_t dev = NODEV;
1766 
1767 	if ((pg = proc_pgrp(p, NULL)) != PGRP_NULL) {
1768 		dev = os_atomic_load(&pg->pg_session->s_ttydev, relaxed);
1769 		pgrp_rele(pg);
1770 	}
1771 
1772 	if (dev == NODEV) {
1773 		return EINVAL;
1774 	}
1775 
1776 	*devp = dev;
1777 	return 0;
1778 }
1779 
1780 int
proc_selfexecutableargs(uint8_t * buf,size_t * buflen)1781 proc_selfexecutableargs(uint8_t *buf, size_t *buflen)
1782 {
1783 	proc_t p = current_proc();
1784 
1785 	// buflen must always be provided
1786 	if (buflen == NULL) {
1787 		return EINVAL;
1788 	}
1789 
1790 	// If a buf is provided, there must be at least enough room to fit argc
1791 	if (buf && *buflen < sizeof(p->p_argc)) {
1792 		return EINVAL;
1793 	}
1794 
1795 	if (!p->user_stack) {
1796 		return EINVAL;
1797 	}
1798 
1799 	if (buf == NULL) {
1800 		*buflen = p->p_argslen + sizeof(p->p_argc);
1801 		return 0;
1802 	}
1803 
1804 	// Copy in argc to the first 4 bytes
1805 	memcpy(buf, &p->p_argc, sizeof(p->p_argc));
1806 
1807 	if (*buflen > sizeof(p->p_argc) && p->p_argslen > 0) {
1808 		// See memory layout comment in kern_exec.c:exec_copyout_strings()
1809 		// We want to copy starting from `p_argslen` bytes away from top of stack
1810 		return copyin(p->user_stack - p->p_argslen,
1811 		           buf + sizeof(p->p_argc),
1812 		           MIN(p->p_argslen, *buflen - sizeof(p->p_argc)));
1813 	} else {
1814 		return 0;
1815 	}
1816 }
1817 
1818 off_t
proc_getexecutableoffset(proc_t p)1819 proc_getexecutableoffset(proc_t p)
1820 {
1821 	return p->p_textoff;
1822 }
1823 
1824 void
bsd_set_dependency_capable(task_t task)1825 bsd_set_dependency_capable(task_t task)
1826 {
1827 	proc_t p = get_bsdtask_info(task);
1828 
1829 	if (p) {
1830 		OSBitOrAtomic(P_DEPENDENCY_CAPABLE, &p->p_flag);
1831 	}
1832 }
1833 
1834 
1835 #ifndef __arm__
1836 int
IS_64BIT_PROCESS(proc_t p)1837 IS_64BIT_PROCESS(proc_t p)
1838 {
1839 	if (p && (p->p_flag & P_LP64)) {
1840 		return 1;
1841 	} else {
1842 		return 0;
1843 	}
1844 }
1845 #endif
1846 
1847 /*
1848  * Locate a process by number
1849  */
1850 proc_t
phash_find_locked(pid_t pid)1851 phash_find_locked(pid_t pid)
1852 {
1853 	proc_t p;
1854 
1855 	LCK_MTX_ASSERT(&proc_list_mlock, LCK_MTX_ASSERT_OWNED);
1856 
1857 	if (!pid) {
1858 		return kernproc;
1859 	}
1860 
1861 	for (p = hazard_ptr_serialized_load(PIDHASH(pid)); p;
1862 	    p = hazard_ptr_serialized_load(&p->p_hash)) {
1863 		if (p->p_proc_ro && p->p_pid == pid) {
1864 			break;
1865 		}
1866 	}
1867 
1868 	return p;
1869 }
1870 
1871 void
phash_insert_locked(pid_t pid,struct proc * p)1872 phash_insert_locked(pid_t pid, struct proc *p)
1873 {
1874 	struct proc_hp *head = PIDHASH(pid);
1875 
1876 	LCK_MTX_ASSERT(&proc_list_mlock, LCK_MTX_ASSERT_OWNED);
1877 
1878 	hazard_ptr_serialized_store_relaxed(&p->p_hash,
1879 	    hazard_ptr_serialized_load(head));
1880 	hazard_ptr_serialized_store(head, p);
1881 }
1882 
1883 void
phash_remove_locked(pid_t pid,struct proc * p)1884 phash_remove_locked(pid_t pid, struct proc *p)
1885 {
1886 	struct proc_hp *prev = PIDHASH(pid);
1887 	struct proc *pn;
1888 
1889 	LCK_MTX_ASSERT(&proc_list_mlock, LCK_MTX_ASSERT_OWNED);
1890 
1891 	while ((pn = hazard_ptr_serialized_load(prev)) != p) {
1892 		prev = &pn->p_hash;
1893 	}
1894 
1895 	/*
1896 	 * Now that the proc is no longer in the hash,
1897 	 * it needs to keep its p_hash value alive.
1898 	 */
1899 	pn = hazard_ptr_serialized_load(&p->p_hash);
1900 	if (pn) {
1901 		os_ref_retain_raw(&pn->p_waitref, &p_refgrp);
1902 	}
1903 	hazard_ptr_serialized_store_relaxed(prev, pn);
1904 }
1905 
1906 proc_t
proc_find(int pid)1907 proc_find(int pid)
1908 {
1909 	struct proc_hp *hp = PIDHASH(pid);
1910 	proc_t p = PROC_NULL;
1911 	hazard_guard_array_t g;
1912 	uint32_t bits = 0;
1913 
1914 	LCK_MTX_ASSERT(&proc_list_mlock, LCK_MTX_ASSERT_NOTOWNED);
1915 
1916 	if (!pid) {
1917 		return proc_ref(kernproc, false);
1918 	}
1919 
1920 	g = hazard_guard_get_n(0, 3);
1921 
1922 	/*
1923 	 * Note: In theory, reusing a guard needs to use hazard_guard_reacquire(),
1924 	 *       however, using 3 guards helps us being smarter:
1925 	 *
1926 	 *       If one considers the sequence of guards being acquired be:
1927 	 *       <n>, <n+1>, <n+2>, <n+3> ...
1928 	 *
1929 	 *       then the pointer acquired at step <n> is used to acquire
1930 	 *       <n+1> but no longer used once <n+2> has been acquired.
1931 	 *
1932 	 *       Acquiring <n+2> has a full barrier which we can hence
1933 	 *       piggy back on, and make the <n+3> reuse of the same guard
1934 	 *       as <n> be an "acquire" instead of a "re-acquire".
1935 	 *
1936 	 *       This unrolling is good for the CPU too since it can help it
1937 	 *       speculate through values/barriers anyway.
1938 	 */
1939 	for (;;) {
1940 		p = hazard_guard_acquire(&g[0], hp);
1941 		if (p == PROC_NULL ||
1942 		    (p->p_pid == pid && p->p_proc_ro != NULL)) {
1943 			break;
1944 		}
1945 		hp = &p->p_hash;
1946 
1947 		p = hazard_guard_acquire(&g[1], hp);
1948 		if (p == PROC_NULL ||
1949 		    (p->p_pid == pid && p->p_proc_ro != NULL)) {
1950 			break;
1951 		}
1952 		hp = &p->p_hash;
1953 
1954 		p = hazard_guard_acquire(&g[2], hp);
1955 		if (p == PROC_NULL ||
1956 		    (p->p_pid == pid && p->p_proc_ro != NULL)) {
1957 			break;
1958 		}
1959 		hp = &p->p_hash;
1960 	}
1961 
1962 	if (p) {
1963 		bits = proc_ref_try_fast(p);
1964 	}
1965 
1966 	hazard_guard_put_n(g, 3);
1967 
1968 	if (__improbable(!bits)) {
1969 		return PROC_NULL;
1970 	}
1971 
1972 	if (__improbable(proc_ref_needs_wait_for_exec(bits))) {
1973 		p = proc_ref_wait_for_exec(p, bits, false);
1974 	}
1975 
1976 	if (p != PROC_NULL) {
1977 		/*
1978 		 * pair with proc_refwake_did_exec() to be able to observe
1979 		 * a fully formed proc_ro structure.
1980 		 */
1981 		os_atomic_thread_fence(acquire);
1982 	}
1983 
1984 	return p;
1985 }
1986 
1987 proc_t
proc_find_locked(int pid)1988 proc_find_locked(int pid)
1989 {
1990 	proc_t p = PROC_NULL;
1991 
1992 	p = phash_find_locked(pid);
1993 	if (p != PROC_NULL) {
1994 		p = proc_ref(p, true);
1995 	}
1996 
1997 	return p;
1998 }
1999 
2000 proc_t
proc_findthread(thread_t thread)2001 proc_findthread(thread_t thread)
2002 {
2003 	proc_t p = PROC_NULL;
2004 
2005 	proc_list_lock();
2006 	{
2007 		p = (proc_t)(get_bsdthreadtask_info(thread));
2008 	}
2009 	p = proc_ref(p, true);
2010 	proc_list_unlock();
2011 	return p;
2012 }
2013 
2014 
2015 /*
2016  * Locate a zombie by PID
2017  */
2018 __private_extern__ proc_t
pzfind(pid_t pid)2019 pzfind(pid_t pid)
2020 {
2021 	proc_t p;
2022 
2023 
2024 	proc_list_lock();
2025 
2026 	LIST_FOREACH(p, &zombproc, p_list) {
2027 		if (proc_getpid(p) == pid) {
2028 			break;
2029 		}
2030 	}
2031 
2032 	proc_list_unlock();
2033 
2034 	return p;
2035 }
2036 
2037 /*
2038  * Acquire a pgrp ref, if and only if the pgrp is non empty.
2039  */
2040 static inline bool
pg_ref_try(struct pgrp * pgrp)2041 pg_ref_try(struct pgrp *pgrp)
2042 {
2043 	return os_ref_retain_try_mask(&pgrp->pg_refcount, PGRP_REF_BITS,
2044 	           PGRP_REF_EMPTY, &p_refgrp);
2045 }
2046 
2047 /*
2048  * Unconditionally acquire a pgrp ref,
2049  * regardless of whether the pgrp is empty or not.
2050  */
2051 static inline struct pgrp *
pg_ref(struct pgrp * pgrp)2052 pg_ref(struct pgrp *pgrp)
2053 {
2054 	os_ref_retain_mask(&pgrp->pg_refcount, PGRP_REF_BITS, &p_refgrp);
2055 	return pgrp;
2056 }
2057 
2058 /*
2059  * Locate a process group by number
2060  */
2061 struct pgrp *
pghash_find_locked(pid_t pgid)2062 pghash_find_locked(pid_t pgid)
2063 {
2064 	struct pgrp *pgrp;
2065 
2066 	LCK_MTX_ASSERT(&proc_list_mlock, LCK_MTX_ASSERT_OWNED);
2067 
2068 	for (pgrp = hazard_ptr_serialized_load(PGRPHASH(pgid)); pgrp;
2069 	    pgrp = hazard_ptr_serialized_load(&pgrp->pg_hash)) {
2070 		if (pgrp->pg_id == pgid) {
2071 			break;
2072 		}
2073 	}
2074 
2075 	return pgrp;
2076 }
2077 
2078 void
pghash_insert_locked(pid_t pgid,struct pgrp * pgrp)2079 pghash_insert_locked(pid_t pgid, struct pgrp *pgrp)
2080 {
2081 	struct pgrp_hp *head = PGRPHASH(pgid);
2082 
2083 	LCK_MTX_ASSERT(&proc_list_mlock, LCK_MTX_ASSERT_OWNED);
2084 
2085 	hazard_ptr_serialized_store_relaxed(&pgrp->pg_hash,
2086 	    hazard_ptr_serialized_load(head));
2087 	hazard_ptr_serialized_store(head, pgrp);
2088 }
2089 
2090 static void
pghash_remove_locked(pid_t pgid,struct pgrp * pgrp)2091 pghash_remove_locked(pid_t pgid, struct pgrp *pgrp)
2092 {
2093 	struct pgrp_hp *prev = PGRPHASH(pgid);
2094 	struct pgrp *pgn;
2095 
2096 	LCK_MTX_ASSERT(&proc_list_mlock, LCK_MTX_ASSERT_OWNED);
2097 
2098 	while ((pgn = hazard_ptr_serialized_load(prev)) != pgrp) {
2099 		prev = &pgn->pg_hash;
2100 	}
2101 
2102 	/*
2103 	 * Now that the process group is out of the hash,
2104 	 * we need to protect its "next" for readers until
2105 	 * its death.
2106 	 */
2107 	pgn = hazard_ptr_serialized_load(&pgrp->pg_hash);
2108 	if (pgn) {
2109 		os_ref_retain_raw(&pgn->pg_hashref, &p_refgrp);
2110 	}
2111 	hazard_ptr_serialized_store_relaxed(prev, pgn);
2112 }
2113 
2114 struct pgrp *
pgrp_find(pid_t pgid)2115 pgrp_find(pid_t pgid)
2116 {
2117 	struct pgrp_hp *hp = PGRPHASH(pgid);
2118 	struct pgrp *pgrp = PGRP_NULL;
2119 	hazard_guard_array_t g;
2120 
2121 	LCK_MTX_ASSERT(&proc_list_mlock, LCK_MTX_ASSERT_NOTOWNED);
2122 
2123 	g = hazard_guard_get_n(0, 3);
2124 
2125 	for (;;) {
2126 		pgrp = hazard_guard_acquire(&g[0], hp);
2127 		if (pgrp == PGRP_NULL || pgrp->pg_id == pgid) {
2128 			break;
2129 		}
2130 		hp = &pgrp->pg_hash;
2131 
2132 		pgrp = hazard_guard_acquire(&g[1], hp);
2133 		if (pgrp == PGRP_NULL || pgrp->pg_id == pgid) {
2134 			break;
2135 		}
2136 		hp = &pgrp->pg_hash;
2137 
2138 		pgrp = hazard_guard_acquire(&g[2], hp);
2139 		if (pgrp == PGRP_NULL || pgrp->pg_id == pgid) {
2140 			break;
2141 		}
2142 		hp = &pgrp->pg_hash;
2143 	}
2144 
2145 	if (pgrp && !pg_ref_try(pgrp)) {
2146 		pgrp = PGRP_NULL;
2147 	}
2148 
2149 	hazard_guard_put_n(g, 3);
2150 
2151 	return pgrp;
2152 }
2153 
2154 /* consumes one ref from pgrp */
2155 static void
pgrp_add_member(struct pgrp * pgrp,struct proc * parent,struct proc * p)2156 pgrp_add_member(struct pgrp *pgrp, struct proc *parent, struct proc *p)
2157 {
2158 	LCK_MTX_ASSERT(&proc_list_mlock, LCK_MTX_ASSERT_OWNED);
2159 
2160 	pgrp_lock(pgrp);
2161 	if (LIST_EMPTY(&pgrp->pg_members)) {
2162 		os_atomic_andnot(&pgrp->pg_refcount, PGRP_REF_EMPTY, relaxed);
2163 	}
2164 	if (parent != PROC_NULL) {
2165 		assert(pgrp == hazard_ptr_serialized_load(&parent->p_pgrp));
2166 		LIST_INSERT_AFTER(parent, p, p_pglist);
2167 	} else {
2168 		LIST_INSERT_HEAD(&pgrp->pg_members, p, p_pglist);
2169 	}
2170 	pgrp_unlock(pgrp);
2171 
2172 	p->p_pgrpid = pgrp->pg_id;
2173 	p->p_sessionid = pgrp->pg_session->s_sid;
2174 	hazard_ptr_serialized_store(&p->p_pgrp, pgrp);
2175 }
2176 
2177 /* returns one ref from pgrp */
2178 static void
pgrp_del_member(struct pgrp * pgrp,struct proc * p)2179 pgrp_del_member(struct pgrp *pgrp, struct proc *p)
2180 {
2181 	LCK_MTX_ASSERT(&proc_list_mlock, LCK_MTX_ASSERT_OWNED);
2182 
2183 	pgrp_lock(pgrp);
2184 	LIST_REMOVE(p, p_pglist);
2185 	if (LIST_EMPTY(&pgrp->pg_members)) {
2186 		os_atomic_or(&pgrp->pg_refcount, PGRP_REF_EMPTY, relaxed);
2187 	}
2188 	pgrp_unlock(pgrp);
2189 }
2190 
2191 void
pgrp_rele(struct pgrp * pgrp)2192 pgrp_rele(struct pgrp * pgrp)
2193 {
2194 	if (pgrp == PGRP_NULL) {
2195 		return;
2196 	}
2197 
2198 	if (os_ref_release_mask(&pgrp->pg_refcount, PGRP_REF_BITS, &p_refgrp) == 0) {
2199 		pgrp_destroy(pgrp);
2200 	}
2201 }
2202 
2203 struct session *
session_alloc(proc_t leader)2204 session_alloc(proc_t leader)
2205 {
2206 	struct session *sess;
2207 
2208 	sess = zalloc_flags(session_zone, Z_WAITOK | Z_ZERO | Z_NOFAIL);
2209 	lck_mtx_init(&sess->s_mlock, &proc_mlock_grp, &proc_lck_attr);
2210 	sess->s_leader = leader;
2211 	sess->s_sid = proc_getpid(leader);
2212 	sess->s_ttypgrpid = NO_PID;
2213 	os_atomic_init(&sess->s_ttydev, NODEV);
2214 	os_ref_init_mask(&sess->s_refcount, SESSION_REF_BITS,
2215 	    &p_refgrp, S_DEFAULT);
2216 
2217 	return sess;
2218 }
2219 
2220 struct tty *
session_set_tty_locked(struct session * sessp,struct tty * tp)2221 session_set_tty_locked(struct session *sessp, struct tty *tp)
2222 {
2223 	struct tty *old;
2224 
2225 	LCK_MTX_ASSERT(&sessp->s_mlock, LCK_MTX_ASSERT_OWNED);
2226 
2227 	old = sessp->s_ttyp;
2228 	ttyhold(tp);
2229 	sessp->s_ttyp = tp;
2230 	os_atomic_store(&sessp->s_ttydev, tp->t_dev, relaxed);
2231 
2232 	return old;
2233 }
2234 
2235 struct tty *
session_clear_tty_locked(struct session * sessp)2236 session_clear_tty_locked(struct session *sessp)
2237 {
2238 	struct tty *tp = sessp->s_ttyp;
2239 
2240 	LCK_MTX_ASSERT(&sessp->s_mlock, LCK_MTX_ASSERT_OWNED);
2241 	sessp->s_ttyvp = NULLVP;
2242 	sessp->s_ttyvid = 0;
2243 	sessp->s_ttyp = TTY_NULL;
2244 	sessp->s_ttypgrpid = NO_PID;
2245 	os_atomic_store(&sessp->s_ttydev, NODEV, relaxed);
2246 
2247 	return tp;
2248 }
2249 
2250 __attribute__((noinline))
2251 static void
session_destroy(struct session * sess)2252 session_destroy(struct session *sess)
2253 {
2254 	proc_list_lock();
2255 	LIST_REMOVE(sess, s_hash);
2256 	proc_list_unlock();
2257 
2258 	/*
2259 	 * Either the TTY was closed,
2260 	 * or proc_exit() destroyed it when the leader went away
2261 	 */
2262 	assert(sess->s_ttyp == TTY_NULL);
2263 
2264 	lck_mtx_destroy(&sess->s_mlock, &proc_mlock_grp);
2265 	zfree(session_zone, sess);
2266 }
2267 
2268 struct session *
session_ref(struct session * sess)2269 session_ref(struct session *sess)
2270 {
2271 	os_ref_retain_mask(&sess->s_refcount, SESSION_REF_BITS, &p_refgrp);
2272 	return sess;
2273 }
2274 
2275 void
session_rele(struct session * sess)2276 session_rele(struct session *sess)
2277 {
2278 	if (os_ref_release_mask(&sess->s_refcount, SESSION_REF_BITS, &p_refgrp) == 0) {
2279 		session_destroy(sess);
2280 	}
2281 }
2282 
2283 
2284 /*
2285  * Make a new process ready to become a useful member of society by making it
2286  * visible in all the right places and initialize its own lists to empty.
2287  *
2288  * Parameters:	parent			The parent of the process to insert
2289  *		child			The child process to insert
2290  *
2291  * Returns:	(void)
2292  *
2293  * Notes:	Insert a child process into the parents children list, assign
2294  *		the child the parent process pointer and PPID of the parent...
2295  */
2296 void
pinsertchild(proc_t parent,proc_t child)2297 pinsertchild(proc_t parent, proc_t child)
2298 {
2299 	LIST_INIT(&child->p_children);
2300 	child->p_pptr = parent;
2301 	child->p_ppid = proc_getpid(parent);
2302 	child->p_original_ppid = proc_getpid(parent);
2303 	child->p_puniqueid = proc_uniqueid(parent);
2304 	child->p_xhighbits = 0;
2305 
2306 	proc_list_lock();
2307 #if CONFIG_MEMORYSTATUS
2308 	memorystatus_add(child, TRUE);
2309 #endif
2310 
2311 	parent->p_childrencnt++;
2312 	LIST_INSERT_HEAD(&parent->p_children, child, p_sibling);
2313 
2314 	LIST_INSERT_HEAD(&allproc, child, p_list);
2315 	/* mark the completion of proc creation */
2316 	os_atomic_andnot(&child->p_refcount, P_REF_NEW, relaxed);
2317 
2318 	proc_list_unlock();
2319 }
2320 
2321 /*
2322  * Move p to a new or existing process group (and session)
2323  *
2324  * Returns:	0			Success
2325  *		ESRCH			No such process
2326  */
2327 int
enterpgrp(proc_t p,pid_t pgid,int mksess)2328 enterpgrp(proc_t p, pid_t pgid, int mksess)
2329 {
2330 	struct pgrp *pgrp;
2331 	struct pgrp *mypgrp;
2332 	struct session *procsp;
2333 
2334 	pgrp = pgrp_find(pgid);
2335 	mypgrp = proc_pgrp(p, &procsp);
2336 
2337 #if DIAGNOSTIC
2338 	if (pgrp != NULL && mksess) {   /* firewalls */
2339 		panic("enterpgrp: setsid into non-empty pgrp");
2340 	}
2341 	if (SESS_LEADER(p, mypgrp->pg_session)) {
2342 		panic("enterpgrp: session leader attempted setpgrp");
2343 	}
2344 #endif
2345 	if (pgrp == PGRP_NULL) {
2346 		struct session *sess;
2347 		pid_t savepid = proc_getpid(p);
2348 		proc_t np = PROC_NULL;
2349 
2350 		/*
2351 		 * new process group
2352 		 */
2353 #if DIAGNOSTIC
2354 		if (proc_getpid(p) != pgid) {
2355 			panic("enterpgrp: new pgrp and pid != pgid");
2356 		}
2357 #endif
2358 		if ((np = proc_find(savepid)) == NULL || np != p) {
2359 			if (np != PROC_NULL) {
2360 				proc_rele(np);
2361 			}
2362 			pgrp_rele(mypgrp);
2363 			return ESRCH;
2364 		}
2365 		proc_rele(np);
2366 
2367 		pgrp = pgrp_alloc(pgid, PGRP_REF_EMPTY);
2368 
2369 		if (mksess) {
2370 			/*
2371 			 * new session
2372 			 */
2373 			sess = session_alloc(p);
2374 
2375 			bcopy(mypgrp->pg_session->s_login, sess->s_login,
2376 			    sizeof(sess->s_login));
2377 			os_atomic_andnot(&p->p_flag, P_CONTROLT, relaxed);
2378 		} else {
2379 			sess = session_ref(procsp);
2380 		}
2381 
2382 		proc_list_lock();
2383 		pgrp->pg_session = sess;
2384 		p->p_sessionid = sess->s_sid;
2385 		pghash_insert_locked(pgid, pgrp);
2386 		if (mksess) {
2387 			LIST_INSERT_HEAD(SESSHASH(sess->s_sid), sess, s_hash);
2388 		}
2389 		proc_list_unlock();
2390 	} else if (pgrp == mypgrp) {
2391 		pgrp_rele(pgrp);
2392 		pgrp_rele(mypgrp);
2393 		return 0;
2394 	}
2395 
2396 	/*
2397 	 * Adjust eligibility of affected pgrps to participate in job control.
2398 	 * Increment eligibility counts before decrementing, otherwise we
2399 	 * could reach 0 spuriously during the first call.
2400 	 */
2401 	fixjobc(p, pgrp, 1);
2402 	fixjobc(p, mypgrp, 0);
2403 
2404 	pgrp_rele(mypgrp);
2405 	pgrp_replace(p, pgrp);
2406 
2407 	return 0;
2408 }
2409 
2410 /*
2411  * remove process from process group
2412  */
2413 struct pgrp *
pgrp_leave_locked(proc_t p)2414 pgrp_leave_locked(proc_t p)
2415 {
2416 	struct pgrp *pg;
2417 
2418 	LCK_MTX_ASSERT(&proc_list_mlock, LCK_MTX_ASSERT_OWNED);
2419 
2420 	pg = hazard_ptr_serialized_load(&p->p_pgrp);
2421 	pgrp_del_member(pg, p);
2422 	p->p_pgrpid = PGRPID_DEAD;
2423 	hazard_ptr_clear(&p->p_pgrp);
2424 
2425 	return pg;
2426 }
2427 
2428 struct pgrp *
pgrp_enter_locked(struct proc * parent,struct proc * child)2429 pgrp_enter_locked(struct proc *parent, struct proc *child)
2430 {
2431 	struct pgrp *pgrp;
2432 
2433 	LCK_MTX_ASSERT(&proc_list_mlock, LCK_MTX_ASSERT_OWNED);
2434 
2435 	pgrp = pg_ref(hazard_ptr_serialized_load(&parent->p_pgrp));
2436 	pgrp_add_member(pgrp, parent, child);
2437 	return pgrp;
2438 }
2439 
2440 /*
2441  * delete a process group
2442  */
2443 static void
pgrp_free(void * _pg)2444 pgrp_free(void *_pg)
2445 {
2446 	struct pgrp *pg = _pg;
2447 	struct pgrp *pgn = hazard_ptr_serialized_load(&pg->pg_hash);
2448 
2449 	if (pgn && os_ref_release_raw(&pgn->pg_hashref, &p_refgrp) == 0) {
2450 		/* release the reference taken in pghash_remove_locked() */
2451 		hazard_retire(pgn, sizeof(*pgn), pgrp_free);
2452 	}
2453 	zfree(pgrp_zone, pg);
2454 }
2455 
2456 __attribute__((noinline))
2457 static void
pgrp_destroy(struct pgrp * pgrp)2458 pgrp_destroy(struct pgrp *pgrp)
2459 {
2460 	struct session *sess;
2461 
2462 	assert(LIST_EMPTY(&pgrp->pg_members));
2463 	assert(os_ref_get_raw_mask(&pgrp->pg_refcount) & PGRP_REF_EMPTY);
2464 
2465 	proc_list_lock();
2466 	pghash_remove_locked(pgrp->pg_id, pgrp);
2467 	proc_list_unlock();
2468 
2469 	sess = pgrp->pg_session;
2470 	pgrp->pg_session = SESSION_NULL;
2471 	session_rele(sess);
2472 
2473 	lck_mtx_destroy(&pgrp->pg_mlock, &proc_mlock_grp);
2474 	if (os_ref_release_raw(&pgrp->pg_hashref, &p_refgrp) == 0) {
2475 		hazard_retire(pgrp, sizeof(*pgrp), pgrp_free);
2476 	}
2477 }
2478 
2479 
2480 /*
2481  * Adjust pgrp jobc counters when specified process changes process group.
2482  * We count the number of processes in each process group that "qualify"
2483  * the group for terminal job control (those with a parent in a different
2484  * process group of the same session).  If that count reaches zero, the
2485  * process group becomes orphaned.  Check both the specified process'
2486  * process group and that of its children.
2487  * entering == 0 => p is leaving specified group.
2488  * entering == 1 => p is entering specified group.
2489  */
2490 int
fixjob_callback(proc_t p,void * arg)2491 fixjob_callback(proc_t p, void * arg)
2492 {
2493 	struct fixjob_iterargs *fp;
2494 	struct pgrp * pg, *hispg;
2495 	struct session * mysession, *hissess;
2496 	int entering;
2497 
2498 	fp = (struct fixjob_iterargs *)arg;
2499 	pg = fp->pg;
2500 	mysession = fp->mysession;
2501 	entering = fp->entering;
2502 
2503 	hispg = proc_pgrp(p, &hissess);
2504 
2505 	if (hispg != pg && hissess == mysession) {
2506 		pgrp_lock(hispg);
2507 		if (entering) {
2508 			hispg->pg_jobc++;
2509 			pgrp_unlock(hispg);
2510 		} else if (--hispg->pg_jobc == 0) {
2511 			pgrp_unlock(hispg);
2512 			orphanpg(hispg);
2513 		} else {
2514 			pgrp_unlock(hispg);
2515 		}
2516 	}
2517 	pgrp_rele(hispg);
2518 
2519 	return PROC_RETURNED;
2520 }
2521 
2522 void
fixjobc(proc_t p,struct pgrp * pgrp,int entering)2523 fixjobc(proc_t p, struct pgrp *pgrp, int entering)
2524 {
2525 	struct pgrp *hispgrp = PGRP_NULL;
2526 	struct session *hissess = SESSION_NULL;
2527 	struct session *mysession = pgrp->pg_session;
2528 	proc_t parent;
2529 	struct fixjob_iterargs fjarg;
2530 	boolean_t proc_parent_self;
2531 
2532 	/*
2533 	 * Check if p's parent is current proc, if yes then no need to take
2534 	 * a ref; calling proc_parent with current proc as parent may
2535 	 * deadlock if current proc is exiting.
2536 	 */
2537 	proc_parent_self = proc_parent_is_currentproc(p);
2538 	if (proc_parent_self) {
2539 		parent = current_proc();
2540 	} else {
2541 		parent = proc_parent(p);
2542 	}
2543 
2544 	if (parent != PROC_NULL) {
2545 		hispgrp = proc_pgrp(parent, &hissess);
2546 		if (!proc_parent_self) {
2547 			proc_rele(parent);
2548 		}
2549 	}
2550 
2551 	/*
2552 	 * Check p's parent to see whether p qualifies its own process
2553 	 * group; if so, adjust count for p's process group.
2554 	 */
2555 	if (hispgrp != pgrp && hissess == mysession) {
2556 		pgrp_lock(pgrp);
2557 		if (entering) {
2558 			pgrp->pg_jobc++;
2559 			pgrp_unlock(pgrp);
2560 		} else if (--pgrp->pg_jobc == 0) {
2561 			pgrp_unlock(pgrp);
2562 			orphanpg(pgrp);
2563 		} else {
2564 			pgrp_unlock(pgrp);
2565 		}
2566 	}
2567 
2568 	pgrp_rele(hispgrp);
2569 
2570 	/*
2571 	 * Check this process' children to see whether they qualify
2572 	 * their process groups; if so, adjust counts for children's
2573 	 * process groups.
2574 	 */
2575 	fjarg.pg = pgrp;
2576 	fjarg.mysession = mysession;
2577 	fjarg.entering = entering;
2578 	proc_childrenwalk(p, fixjob_callback, &fjarg);
2579 }
2580 
2581 /*
2582  * The pidlist_* routines support the functions in this file that
2583  * walk lists of processes applying filters and callouts to the
2584  * elements of the list.
2585  *
2586  * A prior implementation used a single linear array, which can be
2587  * tricky to allocate on large systems. This implementation creates
2588  * an SLIST of modestly sized arrays of PIDS_PER_ENTRY elements.
2589  *
2590  * The array should be sized large enough to keep the overhead of
2591  * walking the list low, but small enough that blocking allocations of
2592  * pidlist_entry_t structures always succeed.
2593  */
2594 
2595 #define PIDS_PER_ENTRY 1021
2596 
2597 typedef struct pidlist_entry {
2598 	SLIST_ENTRY(pidlist_entry) pe_link;
2599 	u_int pe_nused;
2600 	pid_t pe_pid[PIDS_PER_ENTRY];
2601 } pidlist_entry_t;
2602 
2603 typedef struct {
2604 	SLIST_HEAD(, pidlist_entry) pl_head;
2605 	struct pidlist_entry *pl_active;
2606 	u_int pl_nalloc;
2607 } pidlist_t;
2608 
2609 static __inline__ pidlist_t *
pidlist_init(pidlist_t * pl)2610 pidlist_init(pidlist_t *pl)
2611 {
2612 	SLIST_INIT(&pl->pl_head);
2613 	pl->pl_active = NULL;
2614 	pl->pl_nalloc = 0;
2615 	return pl;
2616 }
2617 
2618 static u_int
pidlist_alloc(pidlist_t * pl,u_int needed)2619 pidlist_alloc(pidlist_t *pl, u_int needed)
2620 {
2621 	while (pl->pl_nalloc < needed) {
2622 		pidlist_entry_t *pe = kalloc_type(pidlist_entry_t,
2623 		    Z_WAITOK | Z_ZERO | Z_NOFAIL);
2624 		SLIST_INSERT_HEAD(&pl->pl_head, pe, pe_link);
2625 		pl->pl_nalloc += (sizeof(pe->pe_pid) / sizeof(pe->pe_pid[0]));
2626 	}
2627 	return pl->pl_nalloc;
2628 }
2629 
2630 static void
pidlist_free(pidlist_t * pl)2631 pidlist_free(pidlist_t *pl)
2632 {
2633 	pidlist_entry_t *pe;
2634 	while (NULL != (pe = SLIST_FIRST(&pl->pl_head))) {
2635 		SLIST_FIRST(&pl->pl_head) = SLIST_NEXT(pe, pe_link);
2636 		kfree_type(pidlist_entry_t, pe);
2637 	}
2638 	pl->pl_nalloc = 0;
2639 }
2640 
2641 static __inline__ void
pidlist_set_active(pidlist_t * pl)2642 pidlist_set_active(pidlist_t *pl)
2643 {
2644 	pl->pl_active = SLIST_FIRST(&pl->pl_head);
2645 	assert(pl->pl_active);
2646 }
2647 
2648 static void
pidlist_add_pid(pidlist_t * pl,pid_t pid)2649 pidlist_add_pid(pidlist_t *pl, pid_t pid)
2650 {
2651 	pidlist_entry_t *pe = pl->pl_active;
2652 	if (pe->pe_nused >= sizeof(pe->pe_pid) / sizeof(pe->pe_pid[0])) {
2653 		if (NULL == (pe = SLIST_NEXT(pe, pe_link))) {
2654 			panic("pidlist allocation exhausted");
2655 		}
2656 		pl->pl_active = pe;
2657 	}
2658 	pe->pe_pid[pe->pe_nused++] = pid;
2659 }
2660 
2661 static __inline__ u_int
pidlist_nalloc(const pidlist_t * pl)2662 pidlist_nalloc(const pidlist_t *pl)
2663 {
2664 	return pl->pl_nalloc;
2665 }
2666 
2667 /*
2668  * A process group has become orphaned; if there are any stopped processes in
2669  * the group, hang-up all process in that group.
2670  */
2671 static void
orphanpg(struct pgrp * pgrp)2672 orphanpg(struct pgrp *pgrp)
2673 {
2674 	pidlist_t pid_list, *pl = pidlist_init(&pid_list);
2675 	u_int pid_count_available = 0;
2676 	proc_t p;
2677 
2678 	/* allocate outside of the pgrp_lock */
2679 	for (;;) {
2680 		pgrp_lock(pgrp);
2681 
2682 		boolean_t should_iterate = FALSE;
2683 		pid_count_available = 0;
2684 
2685 		PGMEMBERS_FOREACH(pgrp, p) {
2686 			pid_count_available++;
2687 			if (p->p_stat == SSTOP) {
2688 				should_iterate = TRUE;
2689 			}
2690 		}
2691 		if (pid_count_available == 0 || !should_iterate) {
2692 			pgrp_unlock(pgrp);
2693 			goto out; /* no orphaned processes OR nothing stopped */
2694 		}
2695 		if (pidlist_nalloc(pl) >= pid_count_available) {
2696 			break;
2697 		}
2698 		pgrp_unlock(pgrp);
2699 
2700 		pidlist_alloc(pl, pid_count_available);
2701 	}
2702 	pidlist_set_active(pl);
2703 
2704 	u_int pid_count = 0;
2705 	PGMEMBERS_FOREACH(pgrp, p) {
2706 		pidlist_add_pid(pl, proc_pid(p));
2707 		if (++pid_count >= pid_count_available) {
2708 			break;
2709 		}
2710 	}
2711 	pgrp_unlock(pgrp);
2712 
2713 	const pidlist_entry_t *pe;
2714 	SLIST_FOREACH(pe, &(pl->pl_head), pe_link) {
2715 		for (u_int i = 0; i < pe->pe_nused; i++) {
2716 			const pid_t pid = pe->pe_pid[i];
2717 			if (0 == pid) {
2718 				continue; /* skip kernproc */
2719 			}
2720 			p = proc_find(pid);
2721 			if (!p) {
2722 				continue;
2723 			}
2724 			proc_transwait(p, 0);
2725 			pt_setrunnable(p);
2726 			psignal(p, SIGHUP);
2727 			psignal(p, SIGCONT);
2728 			proc_rele(p);
2729 		}
2730 	}
2731 out:
2732 	pidlist_free(pl);
2733 }
2734 
2735 boolean_t
proc_is_translated(proc_t p __unused)2736 proc_is_translated(proc_t p __unused)
2737 {
2738 	return 0;
2739 }
2740 
2741 int
proc_is_classic(proc_t p __unused)2742 proc_is_classic(proc_t p __unused)
2743 {
2744 	return 0;
2745 }
2746 
2747 bool
proc_is_exotic(proc_t p)2748 proc_is_exotic(
2749 	proc_t p)
2750 {
2751 	if (p == NULL) {
2752 		return false;
2753 	}
2754 	return task_is_exotic(proc_task(p));
2755 }
2756 
2757 bool
proc_is_alien(proc_t p)2758 proc_is_alien(
2759 	proc_t p)
2760 {
2761 	if (p == NULL) {
2762 		return false;
2763 	}
2764 	return task_is_alien(proc_task(p));
2765 }
2766 
2767 /* XXX Why does this function exist?  Need to kill it off... */
2768 proc_t
current_proc_EXTERNAL(void)2769 current_proc_EXTERNAL(void)
2770 {
2771 	return current_proc();
2772 }
2773 
2774 int
proc_is_forcing_hfs_case_sensitivity(proc_t p)2775 proc_is_forcing_hfs_case_sensitivity(proc_t p)
2776 {
2777 	return (p->p_vfs_iopolicy & P_VFS_IOPOLICY_FORCE_HFS_CASE_SENSITIVITY) ? 1 : 0;
2778 }
2779 
2780 bool
proc_ignores_content_protection(proc_t p)2781 proc_ignores_content_protection(proc_t p)
2782 {
2783 	return os_atomic_load(&p->p_vfs_iopolicy, relaxed) & P_VFS_IOPOLICY_IGNORE_CONTENT_PROTECTION;
2784 }
2785 
2786 bool
proc_ignores_node_permissions(proc_t p)2787 proc_ignores_node_permissions(proc_t p)
2788 {
2789 	return os_atomic_load(&p->p_vfs_iopolicy, relaxed) & P_VFS_IOPOLICY_IGNORE_NODE_PERMISSIONS;
2790 }
2791 
2792 bool
proc_skip_mtime_update(proc_t p)2793 proc_skip_mtime_update(proc_t p)
2794 {
2795 	return os_atomic_load(&p->p_vfs_iopolicy, relaxed) & P_VFS_IOPOLICY_SKIP_MTIME_UPDATE;
2796 }
2797 
2798 bool
proc_allow_low_space_writes(proc_t p)2799 proc_allow_low_space_writes(proc_t p)
2800 {
2801 	return os_atomic_load(&p->p_vfs_iopolicy, relaxed) & P_VFS_IOPOLICY_ALLOW_LOW_SPACE_WRITES;
2802 }
2803 
2804 
2805 #if CONFIG_COREDUMP
2806 /*
2807  * proc_core_name(name, uid, pid)
2808  * Expand the name described in corefilename, using name, uid, and pid.
2809  * corefilename is a printf-like string, with three format specifiers:
2810  *	%N	name of process ("name")
2811  *	%P	process id (pid)
2812  *	%U	user id (uid)
2813  * For example, "%N.core" is the default; they can be disabled completely
2814  * by using "/dev/null", or all core files can be stored in "/cores/%U/%N-%P".
2815  * This is controlled by the sysctl variable kern.corefile (see above).
2816  */
2817 __private_extern__ int
proc_core_name(const char * name,uid_t uid,pid_t pid,char * cf_name,size_t cf_name_len)2818 proc_core_name(const char *name, uid_t uid, pid_t pid, char *cf_name,
2819     size_t cf_name_len)
2820 {
2821 	const char *format, *appendstr;
2822 	char id_buf[11];                /* Buffer for pid/uid -- max 4B */
2823 	size_t i, l, n;
2824 
2825 	if (cf_name == NULL) {
2826 		goto toolong;
2827 	}
2828 
2829 	format = corefilename;
2830 	for (i = 0, n = 0; n < cf_name_len && format[i]; i++) {
2831 		switch (format[i]) {
2832 		case '%':       /* Format character */
2833 			i++;
2834 			switch (format[i]) {
2835 			case '%':
2836 				appendstr = "%";
2837 				break;
2838 			case 'N':       /* process name */
2839 				appendstr = name;
2840 				break;
2841 			case 'P':       /* process id */
2842 				snprintf(id_buf, sizeof(id_buf), "%u", pid);
2843 				appendstr = id_buf;
2844 				break;
2845 			case 'U':       /* user id */
2846 				snprintf(id_buf, sizeof(id_buf), "%u", uid);
2847 				appendstr = id_buf;
2848 				break;
2849 			case '\0': /* format string ended in % symbol */
2850 				goto endofstring;
2851 			default:
2852 				appendstr = "";
2853 				log(LOG_ERR,
2854 				    "Unknown format character %c in `%s'\n",
2855 				    format[i], format);
2856 			}
2857 			l = strlen(appendstr);
2858 			if ((n + l) >= cf_name_len) {
2859 				goto toolong;
2860 			}
2861 			bcopy(appendstr, cf_name + n, l);
2862 			n += l;
2863 			break;
2864 		default:
2865 			cf_name[n++] = format[i];
2866 		}
2867 	}
2868 	if (format[i] != '\0') {
2869 		goto toolong;
2870 	}
2871 	return 0;
2872 toolong:
2873 	log(LOG_ERR, "pid %ld (%s), uid (%u): corename is too long\n",
2874 	    (long)pid, name, (uint32_t)uid);
2875 	return 1;
2876 endofstring:
2877 	log(LOG_ERR, "pid %ld (%s), uid (%u): unexpected end of string after %% token\n",
2878 	    (long)pid, name, (uint32_t)uid);
2879 	return 1;
2880 }
2881 #endif /* CONFIG_COREDUMP */
2882 
2883 /* Code Signing related routines */
2884 
2885 int
csops(__unused proc_t p,struct csops_args * uap,__unused int32_t * retval)2886 csops(__unused proc_t p, struct csops_args *uap, __unused int32_t *retval)
2887 {
2888 	return csops_internal(uap->pid, uap->ops, uap->useraddr,
2889 	           uap->usersize, USER_ADDR_NULL);
2890 }
2891 
2892 int
csops_audittoken(__unused proc_t p,struct csops_audittoken_args * uap,__unused int32_t * retval)2893 csops_audittoken(__unused proc_t p, struct csops_audittoken_args *uap, __unused int32_t *retval)
2894 {
2895 	if (uap->uaudittoken == USER_ADDR_NULL) {
2896 		return EINVAL;
2897 	}
2898 	return csops_internal(uap->pid, uap->ops, uap->useraddr,
2899 	           uap->usersize, uap->uaudittoken);
2900 }
2901 
2902 static int
csops_copy_token(const void * start,size_t length,user_size_t usize,user_addr_t uaddr)2903 csops_copy_token(const void *start, size_t length, user_size_t usize, user_addr_t uaddr)
2904 {
2905 	char fakeheader[8] = { 0 };
2906 	int error;
2907 
2908 	if (usize < sizeof(fakeheader)) {
2909 		return ERANGE;
2910 	}
2911 
2912 	/* if no blob, fill in zero header */
2913 	if (NULL == start) {
2914 		start = fakeheader;
2915 		length = sizeof(fakeheader);
2916 	} else if (usize < length) {
2917 		/* ... if input too short, copy out length of entitlement */
2918 		uint32_t length32 = htonl((uint32_t)length);
2919 		memcpy(&fakeheader[4], &length32, sizeof(length32));
2920 
2921 		error = copyout(fakeheader, uaddr, sizeof(fakeheader));
2922 		if (error == 0) {
2923 			return ERANGE; /* input buffer to short, ERANGE signals that */
2924 		}
2925 		return error;
2926 	}
2927 	return copyout(start, uaddr, length);
2928 }
2929 
2930 static int
csops_internal(pid_t pid,int ops,user_addr_t uaddr,user_size_t usersize,user_addr_t uaudittoken)2931 csops_internal(pid_t pid, int ops, user_addr_t uaddr, user_size_t usersize, user_addr_t uaudittoken)
2932 {
2933 	size_t usize = (size_t)CAST_DOWN(size_t, usersize);
2934 	proc_t pt;
2935 	int forself;
2936 	int error;
2937 	vnode_t tvp;
2938 	off_t toff;
2939 	unsigned char cdhash[SHA1_RESULTLEN];
2940 	audit_token_t token;
2941 	unsigned int upid = 0, uidversion = 0;
2942 
2943 	forself = error = 0;
2944 
2945 	if (pid == 0) {
2946 		pid = proc_selfpid();
2947 	}
2948 	if (pid == proc_selfpid()) {
2949 		forself = 1;
2950 	}
2951 
2952 
2953 	switch (ops) {
2954 	case CS_OPS_STATUS:
2955 	case CS_OPS_CDHASH:
2956 	case CS_OPS_PIDOFFSET:
2957 	case CS_OPS_ENTITLEMENTS_BLOB:
2958 	case CS_OPS_DER_ENTITLEMENTS_BLOB:
2959 	case CS_OPS_IDENTITY:
2960 	case CS_OPS_BLOB:
2961 	case CS_OPS_TEAMID:
2962 	case CS_OPS_CLEAR_LV:
2963 		break;          /* not restricted to root */
2964 	default:
2965 		if (forself == 0 && kauth_cred_issuser(kauth_cred_get()) != TRUE) {
2966 			return EPERM;
2967 		}
2968 		break;
2969 	}
2970 
2971 	pt = proc_find(pid);
2972 	if (pt == PROC_NULL) {
2973 		return ESRCH;
2974 	}
2975 
2976 	upid = proc_getpid(pt);
2977 	uidversion = proc_pidversion(pt);
2978 	if (uaudittoken != USER_ADDR_NULL) {
2979 		error = copyin(uaudittoken, &token, sizeof(audit_token_t));
2980 		if (error != 0) {
2981 			goto out;
2982 		}
2983 		/* verify the audit token pid/idversion matches with proc */
2984 		if ((token.val[5] != upid) || (token.val[7] != uidversion)) {
2985 			error = ESRCH;
2986 			goto out;
2987 		}
2988 	}
2989 
2990 #if CONFIG_MACF
2991 	switch (ops) {
2992 	case CS_OPS_MARKINVALID:
2993 	case CS_OPS_MARKHARD:
2994 	case CS_OPS_MARKKILL:
2995 	case CS_OPS_MARKRESTRICT:
2996 	case CS_OPS_SET_STATUS:
2997 	case CS_OPS_CLEARINSTALLER:
2998 	case CS_OPS_CLEARPLATFORM:
2999 	case CS_OPS_CLEAR_LV:
3000 		if ((error = mac_proc_check_set_cs_info(current_proc(), pt, ops))) {
3001 			goto out;
3002 		}
3003 		break;
3004 	default:
3005 		if ((error = mac_proc_check_get_cs_info(current_proc(), pt, ops))) {
3006 			goto out;
3007 		}
3008 	}
3009 #endif
3010 
3011 	switch (ops) {
3012 	case CS_OPS_STATUS: {
3013 		uint32_t retflags;
3014 
3015 		proc_lock(pt);
3016 		retflags = (uint32_t)proc_getcsflags(pt);
3017 		if (cs_process_enforcement(pt)) {
3018 			retflags |= CS_ENFORCEMENT;
3019 		}
3020 		if (csproc_get_platform_binary(pt)) {
3021 			retflags |= CS_PLATFORM_BINARY;
3022 		}
3023 		if (csproc_get_platform_path(pt)) {
3024 			retflags |= CS_PLATFORM_PATH;
3025 		}
3026 		//Don't return CS_REQUIRE_LV if we turned it on with CS_FORCED_LV but still report CS_FORCED_LV
3027 		if ((proc_getcsflags(pt) & CS_FORCED_LV) == CS_FORCED_LV) {
3028 			retflags &= (~CS_REQUIRE_LV);
3029 		}
3030 		proc_unlock(pt);
3031 
3032 		if (uaddr != USER_ADDR_NULL) {
3033 			error = copyout(&retflags, uaddr, sizeof(uint32_t));
3034 		}
3035 		break;
3036 	}
3037 	case CS_OPS_MARKINVALID:
3038 		proc_lock(pt);
3039 		if ((proc_getcsflags(pt) & CS_VALID) == CS_VALID) {           /* is currently valid */
3040 			proc_csflags_clear(pt, CS_VALID);       /* set invalid */
3041 			cs_process_invalidated(pt);
3042 			if ((proc_getcsflags(pt) & CS_KILL) == CS_KILL) {
3043 				proc_csflags_set(pt, CS_KILLED);
3044 				proc_unlock(pt);
3045 				if (cs_debug) {
3046 					printf("CODE SIGNING: marked invalid by pid %d: "
3047 					    "p=%d[%s] honoring CS_KILL, final status 0x%x\n",
3048 					    proc_selfpid(), proc_getpid(pt), pt->p_comm,
3049 					    (unsigned int)proc_getcsflags(pt));
3050 				}
3051 				psignal(pt, SIGKILL);
3052 			} else {
3053 				proc_unlock(pt);
3054 			}
3055 		} else {
3056 			proc_unlock(pt);
3057 		}
3058 
3059 		break;
3060 
3061 	case CS_OPS_MARKHARD:
3062 		proc_lock(pt);
3063 		proc_csflags_set(pt, CS_HARD);
3064 		if ((proc_getcsflags(pt) & CS_VALID) == 0) {
3065 			/* @@@ allow? reject? kill? @@@ */
3066 			proc_unlock(pt);
3067 			error = EINVAL;
3068 			goto out;
3069 		} else {
3070 			proc_unlock(pt);
3071 		}
3072 		break;
3073 
3074 	case CS_OPS_MARKKILL:
3075 		proc_lock(pt);
3076 		proc_csflags_set(pt, CS_KILL);
3077 		if ((proc_getcsflags(pt) & CS_VALID) == 0) {
3078 			proc_unlock(pt);
3079 			psignal(pt, SIGKILL);
3080 		} else {
3081 			proc_unlock(pt);
3082 		}
3083 		break;
3084 
3085 	case CS_OPS_PIDOFFSET:
3086 		toff = pt->p_textoff;
3087 		proc_rele(pt);
3088 		error = copyout(&toff, uaddr, sizeof(toff));
3089 		return error;
3090 
3091 	case CS_OPS_CDHASH:
3092 
3093 		/* pt already holds a reference on its p_textvp */
3094 		tvp = pt->p_textvp;
3095 		toff = pt->p_textoff;
3096 
3097 		if (tvp == NULLVP || usize != SHA1_RESULTLEN) {
3098 			proc_rele(pt);
3099 			return EINVAL;
3100 		}
3101 
3102 		error = vn_getcdhash(tvp, toff, cdhash);
3103 		proc_rele(pt);
3104 
3105 		if (error == 0) {
3106 			error = copyout(cdhash, uaddr, sizeof(cdhash));
3107 		}
3108 
3109 		return error;
3110 
3111 	case CS_OPS_ENTITLEMENTS_BLOB: {
3112 		void *start;
3113 		size_t length;
3114 		struct cs_blob* blob;
3115 		bool shouldFreeXML = false;
3116 
3117 		proc_lock(pt);
3118 
3119 		if ((proc_getcsflags(pt) & (CS_VALID | CS_DEBUGGED)) == 0) {
3120 			error = EINVAL;
3121 			goto blob_out;
3122 		}
3123 		blob = csproc_get_blob(pt);
3124 		if (!blob) {
3125 			error = EBADEXEC;
3126 			goto blob_out;
3127 		}
3128 
3129 		if (amfi && csblob_os_entitlements_get(blob)) {
3130 			void* osent = csblob_os_entitlements_get(blob);
3131 			CS_GenericBlob* xmlblob = NULL;
3132 			if (amfi->OSEntitlements_get_xml(osent, &xmlblob)) {
3133 				start = (void*)xmlblob;
3134 				length = (size_t)ntohl(xmlblob->length);
3135 				shouldFreeXML = true;
3136 			} else {
3137 				goto blob_out;
3138 			}
3139 		} else {
3140 			error = cs_entitlements_blob_get(pt, &start, &length);
3141 			if (error) {
3142 				goto blob_out;
3143 			}
3144 		}
3145 
3146 		error = csops_copy_token(start, length, usize, uaddr);
3147 		if (shouldFreeXML) {
3148 			kfree(start, length);
3149 		}
3150 		goto blob_out;
3151 	}
3152 	case CS_OPS_DER_ENTITLEMENTS_BLOB: {
3153 		const void *start;
3154 		size_t length;
3155 		struct cs_blob* blob;
3156 
3157 		proc_lock(pt);
3158 
3159 		if ((proc_getcsflags(pt) & (CS_VALID | CS_DEBUGGED)) == 0) {
3160 			error = EINVAL;
3161 			goto blob_out;
3162 		}
3163 		blob = csproc_get_blob(pt);
3164 		if (!blob) {
3165 			error = EBADEXEC;
3166 			goto blob_out;
3167 		}
3168 
3169 		error = csblob_get_der_entitlements(blob, (const CS_GenericBlob **)&start, &length);
3170 		if (error || start == NULL) {
3171 			if (amfi && csblob_os_entitlements_get(blob)) {
3172 				void* osent = csblob_os_entitlements_get(blob);
3173 
3174 				const CS_GenericBlob* transmuted = NULL;
3175 				if (amfi->OSEntitlements_get_transmuted(osent, &transmuted)) {
3176 					start = transmuted;
3177 					length = (size_t)ntohl(transmuted->length);
3178 				} else {
3179 					goto blob_out;
3180 				}
3181 			} else {
3182 				goto blob_out;
3183 			}
3184 		}
3185 
3186 		error = csops_copy_token(start, length, usize, uaddr);
3187 		goto blob_out;
3188 	}
3189 	case CS_OPS_MARKRESTRICT:
3190 		proc_lock(pt);
3191 		proc_csflags_set(pt, CS_RESTRICT);
3192 		proc_unlock(pt);
3193 		break;
3194 
3195 	case CS_OPS_SET_STATUS: {
3196 		uint32_t flags;
3197 
3198 		if (usize < sizeof(flags)) {
3199 			error = ERANGE;
3200 			break;
3201 		}
3202 
3203 		error = copyin(uaddr, &flags, sizeof(flags));
3204 		if (error) {
3205 			break;
3206 		}
3207 
3208 		/* only allow setting a subset of all code sign flags */
3209 		flags &=
3210 		    CS_HARD | CS_EXEC_SET_HARD |
3211 		    CS_KILL | CS_EXEC_SET_KILL |
3212 		    CS_RESTRICT |
3213 		    CS_REQUIRE_LV |
3214 		    CS_ENFORCEMENT | CS_EXEC_SET_ENFORCEMENT;
3215 
3216 		proc_lock(pt);
3217 		if (proc_getcsflags(pt) & CS_VALID) {
3218 			if ((flags & CS_ENFORCEMENT) &&
3219 			    !(proc_getcsflags(pt) & CS_ENFORCEMENT)) {
3220 				vm_map_cs_enforcement_set(get_task_map(pt->task), TRUE);
3221 			}
3222 			proc_csflags_set(pt, flags);
3223 		} else {
3224 			error = EINVAL;
3225 		}
3226 		proc_unlock(pt);
3227 
3228 		break;
3229 	}
3230 	case CS_OPS_CLEAR_LV: {
3231 		/*
3232 		 * This option is used to remove library validation from
3233 		 * a running process. This is used in plugin architectures
3234 		 * when a program needs to load untrusted libraries. This
3235 		 * allows the process to maintain library validation as
3236 		 * long as possible, then drop it only when required.
3237 		 * Once a process has loaded the untrusted library,
3238 		 * relying on library validation in the future will
3239 		 * not be effective. An alternative is to re-exec
3240 		 * your application without library validation, or
3241 		 * fork an untrusted child.
3242 		 */
3243 #if !defined(XNU_TARGET_OS_OSX)
3244 		// We only support dropping library validation on macOS
3245 		error = ENOTSUP;
3246 #else
3247 		/*
3248 		 * if we have the flag set, and the caller wants
3249 		 * to remove it, and they're entitled to, then
3250 		 * we remove it from the csflags
3251 		 *
3252 		 * NOTE: We are fine to poke into the task because
3253 		 * we get a ref to pt when we do the proc_find
3254 		 * at the beginning of this function.
3255 		 *
3256 		 * We also only allow altering ourselves.
3257 		 */
3258 		if (forself == 1 && IOTaskHasEntitlement(pt->task, CLEAR_LV_ENTITLEMENT)) {
3259 			proc_lock(pt);
3260 			proc_csflags_clear(pt, CS_REQUIRE_LV | CS_FORCED_LV);
3261 			proc_unlock(pt);
3262 			error = 0;
3263 		} else {
3264 			error = EPERM;
3265 		}
3266 #endif
3267 		break;
3268 	}
3269 	case CS_OPS_BLOB: {
3270 		void *start;
3271 		size_t length;
3272 
3273 		proc_lock(pt);
3274 		if ((proc_getcsflags(pt) & (CS_VALID | CS_DEBUGGED)) == 0) {
3275 			proc_unlock(pt);
3276 			error = EINVAL;
3277 			break;
3278 		}
3279 
3280 		error = cs_blob_get(pt, &start, &length);
3281 		if (error) {
3282 			goto blob_out;
3283 		}
3284 
3285 		error = csops_copy_token(start, length, usize, uaddr);
3286 		goto blob_out;
3287 	}
3288 	case CS_OPS_IDENTITY:
3289 	case CS_OPS_TEAMID: {
3290 		const char *identity;
3291 		uint8_t fakeheader[8];
3292 		uint32_t idlen;
3293 		size_t length;
3294 
3295 		/*
3296 		 * Make identity have a blob header to make it
3297 		 * easier on userland to guess the identity
3298 		 * length.
3299 		 */
3300 		if (usize < sizeof(fakeheader)) {
3301 			error = ERANGE;
3302 			break;
3303 		}
3304 		memset(fakeheader, 0, sizeof(fakeheader));
3305 
3306 		proc_lock(pt);
3307 		if ((proc_getcsflags(pt) & (CS_VALID | CS_DEBUGGED)) == 0) {
3308 			proc_unlock(pt);
3309 			error = EINVAL;
3310 			break;
3311 		}
3312 
3313 		identity = ops == CS_OPS_TEAMID ? csproc_get_teamid(pt) : cs_identity_get(pt);
3314 		if (identity == NULL) {
3315 			error = ENOENT;
3316 			goto blob_out;
3317 		}
3318 
3319 		length = strlen(identity) + 1;         /* include NUL */
3320 		idlen = htonl((uint32_t)(length + sizeof(fakeheader)));
3321 		memcpy(&fakeheader[4], &idlen, sizeof(idlen));
3322 
3323 		error = copyout(fakeheader, uaddr, sizeof(fakeheader));
3324 		if (error) {
3325 			goto blob_out;
3326 		}
3327 
3328 		if (usize < sizeof(fakeheader) + length) {
3329 			error = ERANGE;
3330 		} else if (usize > sizeof(fakeheader)) {
3331 			error = copyout(identity, uaddr + sizeof(fakeheader), length);
3332 		}
3333 		goto blob_out;
3334 	}
3335 
3336 	case CS_OPS_CLEARINSTALLER:
3337 		proc_lock(pt);
3338 		proc_csflags_clear(pt, CS_INSTALLER | CS_DATAVAULT_CONTROLLER | CS_EXEC_INHERIT_SIP);
3339 		proc_unlock(pt);
3340 		break;
3341 
3342 	case CS_OPS_CLEARPLATFORM:
3343 #if DEVELOPMENT || DEBUG
3344 		if (cs_process_global_enforcement()) {
3345 			error = ENOTSUP;
3346 			break;
3347 		}
3348 
3349 #if CONFIG_CSR
3350 		if (csr_check(CSR_ALLOW_APPLE_INTERNAL) != 0) {
3351 			error = ENOTSUP;
3352 			break;
3353 		}
3354 #endif
3355 
3356 		proc_lock(pt);
3357 		proc_csflags_clear(pt, CS_PLATFORM_BINARY | CS_PLATFORM_PATH);
3358 		csproc_clear_platform_binary(pt);
3359 		proc_unlock(pt);
3360 		break;
3361 #else
3362 		error = ENOTSUP;
3363 		break;
3364 #endif /* !DEVELOPMENT || DEBUG */
3365 
3366 	default:
3367 		error = EINVAL;
3368 		break;
3369 	}
3370 out:
3371 	proc_rele(pt);
3372 	return error;
3373 blob_out:
3374 	proc_unlock(pt);
3375 	proc_rele(pt);
3376 	return error;
3377 }
3378 
3379 void
proc_iterate(unsigned int flags,proc_iterate_fn_t callout,void * arg,proc_iterate_fn_t filterfn,void * filterarg)3380 proc_iterate(
3381 	unsigned int flags,
3382 	proc_iterate_fn_t callout,
3383 	void *arg,
3384 	proc_iterate_fn_t filterfn,
3385 	void *filterarg)
3386 {
3387 	pidlist_t pid_list, *pl = pidlist_init(&pid_list);
3388 	u_int pid_count_available = 0;
3389 
3390 	assert(callout != NULL);
3391 
3392 	/* allocate outside of the proc_list_lock */
3393 	for (;;) {
3394 		proc_list_lock();
3395 		pid_count_available = nprocs + 1; /* kernel_task not counted in nprocs */
3396 		assert(pid_count_available > 0);
3397 		if (pidlist_nalloc(pl) >= pid_count_available) {
3398 			break;
3399 		}
3400 		proc_list_unlock();
3401 
3402 		pidlist_alloc(pl, pid_count_available);
3403 	}
3404 	pidlist_set_active(pl);
3405 
3406 	/* filter pids into the pid_list */
3407 
3408 	u_int pid_count = 0;
3409 	if (flags & PROC_ALLPROCLIST) {
3410 		proc_t p;
3411 		ALLPROC_FOREACH(p) {
3412 			/* ignore processes that are being forked */
3413 			if (p->p_stat == SIDL) {
3414 				continue;
3415 			}
3416 			if ((filterfn != NULL) && (filterfn(p, filterarg) == 0)) {
3417 				continue;
3418 			}
3419 			pidlist_add_pid(pl, proc_pid(p));
3420 			if (++pid_count >= pid_count_available) {
3421 				break;
3422 			}
3423 		}
3424 	}
3425 
3426 	if ((pid_count < pid_count_available) &&
3427 	    (flags & PROC_ZOMBPROCLIST)) {
3428 		proc_t p;
3429 		ZOMBPROC_FOREACH(p) {
3430 			if ((filterfn != NULL) && (filterfn(p, filterarg) == 0)) {
3431 				continue;
3432 			}
3433 			pidlist_add_pid(pl, proc_pid(p));
3434 			if (++pid_count >= pid_count_available) {
3435 				break;
3436 			}
3437 		}
3438 	}
3439 
3440 	proc_list_unlock();
3441 
3442 	/* call callout on processes in the pid_list */
3443 
3444 	const pidlist_entry_t *pe;
3445 	SLIST_FOREACH(pe, &(pl->pl_head), pe_link) {
3446 		for (u_int i = 0; i < pe->pe_nused; i++) {
3447 			const pid_t pid = pe->pe_pid[i];
3448 			proc_t p = proc_find(pid);
3449 			if (p) {
3450 				if ((flags & PROC_NOWAITTRANS) == 0) {
3451 					proc_transwait(p, 0);
3452 				}
3453 				const int callout_ret = callout(p, arg);
3454 
3455 				switch (callout_ret) {
3456 				case PROC_RETURNED_DONE:
3457 					proc_rele(p);
3458 					OS_FALLTHROUGH;
3459 				case PROC_CLAIMED_DONE:
3460 					goto out;
3461 
3462 				case PROC_RETURNED:
3463 					proc_rele(p);
3464 					OS_FALLTHROUGH;
3465 				case PROC_CLAIMED:
3466 					break;
3467 				default:
3468 					panic("%s: callout =%d for pid %d",
3469 					    __func__, callout_ret, pid);
3470 					break;
3471 				}
3472 			} else if (flags & PROC_ZOMBPROCLIST) {
3473 				p = proc_find_zombref(pid);
3474 				if (!p) {
3475 					continue;
3476 				}
3477 				const int callout_ret = callout(p, arg);
3478 
3479 				switch (callout_ret) {
3480 				case PROC_RETURNED_DONE:
3481 					proc_drop_zombref(p);
3482 					OS_FALLTHROUGH;
3483 				case PROC_CLAIMED_DONE:
3484 					goto out;
3485 
3486 				case PROC_RETURNED:
3487 					proc_drop_zombref(p);
3488 					OS_FALLTHROUGH;
3489 				case PROC_CLAIMED:
3490 					break;
3491 				default:
3492 					panic("%s: callout =%d for zombie %d",
3493 					    __func__, callout_ret, pid);
3494 					break;
3495 				}
3496 			}
3497 		}
3498 	}
3499 out:
3500 	pidlist_free(pl);
3501 }
3502 
3503 void
proc_rebootscan(proc_iterate_fn_t callout,void * arg,proc_iterate_fn_t filterfn,void * filterarg)3504 proc_rebootscan(
3505 	proc_iterate_fn_t callout,
3506 	void *arg,
3507 	proc_iterate_fn_t filterfn,
3508 	void *filterarg)
3509 {
3510 	proc_t p;
3511 
3512 	assert(callout != NULL);
3513 
3514 	proc_shutdown_exitcount = 0;
3515 
3516 restart_foreach:
3517 
3518 	proc_list_lock();
3519 
3520 	ALLPROC_FOREACH(p) {
3521 		if ((filterfn != NULL) && filterfn(p, filterarg) == 0) {
3522 			continue;
3523 		}
3524 		p = proc_ref(p, true);
3525 		if (!p) {
3526 			continue;
3527 		}
3528 
3529 		proc_list_unlock();
3530 
3531 		proc_transwait(p, 0);
3532 		(void)callout(p, arg);
3533 		proc_rele(p);
3534 
3535 		goto restart_foreach;
3536 	}
3537 
3538 	proc_list_unlock();
3539 }
3540 
3541 void
proc_childrenwalk(proc_t parent,proc_iterate_fn_t callout,void * arg)3542 proc_childrenwalk(
3543 	proc_t parent,
3544 	proc_iterate_fn_t callout,
3545 	void *arg)
3546 {
3547 	pidlist_t pid_list, *pl = pidlist_init(&pid_list);
3548 	u_int pid_count_available = 0;
3549 
3550 	assert(parent != NULL);
3551 	assert(callout != NULL);
3552 
3553 	for (;;) {
3554 		proc_list_lock();
3555 		pid_count_available = parent->p_childrencnt;
3556 		if (pid_count_available == 0) {
3557 			proc_list_unlock();
3558 			goto out;
3559 		}
3560 		if (pidlist_nalloc(pl) >= pid_count_available) {
3561 			break;
3562 		}
3563 		proc_list_unlock();
3564 
3565 		pidlist_alloc(pl, pid_count_available);
3566 	}
3567 	pidlist_set_active(pl);
3568 
3569 	u_int pid_count = 0;
3570 	proc_t p;
3571 	PCHILDREN_FOREACH(parent, p) {
3572 		if (p->p_stat == SIDL) {
3573 			continue;
3574 		}
3575 		pidlist_add_pid(pl, proc_pid(p));
3576 		if (++pid_count >= pid_count_available) {
3577 			break;
3578 		}
3579 	}
3580 
3581 	proc_list_unlock();
3582 
3583 	const pidlist_entry_t *pe;
3584 	SLIST_FOREACH(pe, &(pl->pl_head), pe_link) {
3585 		for (u_int i = 0; i < pe->pe_nused; i++) {
3586 			const pid_t pid = pe->pe_pid[i];
3587 			p = proc_find(pid);
3588 			if (!p) {
3589 				continue;
3590 			}
3591 			const int callout_ret = callout(p, arg);
3592 
3593 			switch (callout_ret) {
3594 			case PROC_RETURNED_DONE:
3595 				proc_rele(p);
3596 				OS_FALLTHROUGH;
3597 			case PROC_CLAIMED_DONE:
3598 				goto out;
3599 
3600 			case PROC_RETURNED:
3601 				proc_rele(p);
3602 				OS_FALLTHROUGH;
3603 			case PROC_CLAIMED:
3604 				break;
3605 			default:
3606 				panic("%s: callout =%d for pid %d",
3607 				    __func__, callout_ret, pid);
3608 				break;
3609 			}
3610 		}
3611 	}
3612 out:
3613 	pidlist_free(pl);
3614 }
3615 
3616 void
3617 pgrp_iterate(
3618 	struct pgrp *pgrp,
3619 	proc_iterate_fn_t callout,
3620 	void * arg,
3621 	bool (^filterfn)(proc_t))
3622 {
3623 	pidlist_t pid_list, *pl = pidlist_init(&pid_list);
3624 	u_int pid_count_available = 0;
3625 	proc_t p;
3626 
3627 	assert(pgrp != NULL);
3628 	assert(callout != NULL);
3629 
3630 	for (;;) {
3631 		pgrp_lock(pgrp);
3632 		/*
3633 		 * each member has one ref + some transient holders,
3634 		 * this is a good enough approximation
3635 		 */
3636 		pid_count_available = os_ref_get_count_mask(&pgrp->pg_refcount,
3637 		    PGRP_REF_BITS);
3638 		if (pidlist_nalloc(pl) >= pid_count_available) {
3639 			break;
3640 		}
3641 		pgrp_unlock(pgrp);
3642 
3643 		pidlist_alloc(pl, pid_count_available);
3644 	}
3645 	pidlist_set_active(pl);
3646 
3647 	const pid_t pgid = pgrp->pg_id;
3648 	u_int pid_count = 0;
3649 
PGMEMBERS_FOREACH(pgrp,p)3650 	PGMEMBERS_FOREACH(pgrp, p) {
3651 		if ((filterfn != NULL) && (filterfn(p) == 0)) {
3652 			continue;
3653 		}
3654 		pidlist_add_pid(pl, proc_pid(p));
3655 		if (++pid_count >= pid_count_available) {
3656 			break;
3657 		}
3658 	}
3659 
3660 	pgrp_unlock(pgrp);
3661 
3662 	const pidlist_entry_t *pe;
3663 	SLIST_FOREACH(pe, &(pl->pl_head), pe_link) {
3664 		for (u_int i = 0; i < pe->pe_nused; i++) {
3665 			const pid_t pid = pe->pe_pid[i];
3666 			if (0 == pid) {
3667 				continue; /* skip kernproc */
3668 			}
3669 			p = proc_find(pid);
3670 			if (!p) {
3671 				continue;
3672 			}
3673 			if (p->p_pgrpid != pgid) {
3674 				proc_rele(p);
3675 				continue;
3676 			}
3677 			const int callout_ret = callout(p, arg);
3678 
3679 			switch (callout_ret) {
3680 			case PROC_RETURNED:
3681 				proc_rele(p);
3682 				OS_FALLTHROUGH;
3683 			case PROC_CLAIMED:
3684 				break;
3685 			case PROC_RETURNED_DONE:
3686 				proc_rele(p);
3687 				OS_FALLTHROUGH;
3688 			case PROC_CLAIMED_DONE:
3689 				goto out;
3690 
3691 			default:
3692 				panic("%s: callout =%d for pid %d",
3693 				    __func__, callout_ret, pid);
3694 			}
3695 		}
3696 	}
3697 
3698 out:
3699 	pidlist_free(pl);
3700 }
3701 
3702 /* consumes the newpg ref */
3703 static void
pgrp_replace(struct proc * p,struct pgrp * newpg)3704 pgrp_replace(struct proc *p, struct pgrp *newpg)
3705 {
3706 	struct pgrp *oldpg;
3707 
3708 	proc_list_lock();
3709 	oldpg = hazard_ptr_serialized_load(&p->p_pgrp);
3710 	pgrp_del_member(oldpg, p);
3711 	pgrp_add_member(newpg, PROC_NULL, p);
3712 	proc_list_unlock();
3713 
3714 	pgrp_rele(oldpg);
3715 }
3716 
3717 struct pgrp *
pgrp_alloc(pid_t pgid,pggrp_ref_bits_t bits)3718 pgrp_alloc(pid_t pgid, pggrp_ref_bits_t bits)
3719 {
3720 	struct pgrp *pgrp = zalloc_flags(pgrp_zone, Z_WAITOK | Z_ZERO | Z_NOFAIL);
3721 
3722 	os_ref_init_mask(&pgrp->pg_refcount, PGRP_REF_BITS, &p_refgrp, bits);
3723 	os_ref_init_raw(&pgrp->pg_hashref, &p_refgrp);
3724 	LIST_INIT(&pgrp->pg_members);
3725 	lck_mtx_init(&pgrp->pg_mlock, &proc_mlock_grp, &proc_lck_attr);
3726 	pgrp->pg_id = pgid;
3727 
3728 	return pgrp;
3729 }
3730 
3731 void
pgrp_lock(struct pgrp * pgrp)3732 pgrp_lock(struct pgrp * pgrp)
3733 {
3734 	lck_mtx_lock(&pgrp->pg_mlock);
3735 }
3736 
3737 void
pgrp_unlock(struct pgrp * pgrp)3738 pgrp_unlock(struct pgrp * pgrp)
3739 {
3740 	lck_mtx_unlock(&pgrp->pg_mlock);
3741 }
3742 
3743 struct session *
session_find_locked(pid_t sessid)3744 session_find_locked(pid_t sessid)
3745 {
3746 	struct session *sess;
3747 
3748 	LIST_FOREACH(sess, SESSHASH(sessid), s_hash) {
3749 		if (sess->s_sid == sessid) {
3750 			break;
3751 		}
3752 	}
3753 
3754 	return sess;
3755 }
3756 
3757 void
session_lock(struct session * sess)3758 session_lock(struct session * sess)
3759 {
3760 	lck_mtx_lock(&sess->s_mlock);
3761 }
3762 
3763 
3764 void
session_unlock(struct session * sess)3765 session_unlock(struct session * sess)
3766 {
3767 	lck_mtx_unlock(&sess->s_mlock);
3768 }
3769 
3770 struct pgrp *
proc_pgrp(proc_t p,struct session ** sessp)3771 proc_pgrp(proc_t p, struct session **sessp)
3772 {
3773 	struct pgrp *pgrp = PGRP_NULL;
3774 	hazard_guard_t g;
3775 	bool success = false;
3776 
3777 	if (__probable(p != PROC_NULL)) {
3778 		g = hazard_guard_get(0);
3779 		pgrp = hazard_guard_acquire(g, &p->p_pgrp);
3780 		success = pgrp == PGRP_NULL || pg_ref_try(pgrp);
3781 		hazard_guard_put(g);
3782 
3783 		if (__improbable(!success)) {
3784 			/*
3785 			 * We caught the process in the middle of pgrp_replace(),
3786 			 * go the slow, never failing way.
3787 			 */
3788 			proc_list_lock();
3789 			pgrp = pg_ref(hazard_ptr_serialized_load(&p->p_pgrp));
3790 			proc_list_unlock();
3791 		}
3792 	}
3793 
3794 	if (sessp) {
3795 		*sessp = pgrp ? pgrp->pg_session : SESSION_NULL;
3796 	}
3797 	return pgrp;
3798 }
3799 
3800 struct pgrp *
tty_pgrp_locked(struct tty * tp)3801 tty_pgrp_locked(struct tty *tp)
3802 {
3803 	struct pgrp *pg = PGRP_NULL;
3804 
3805 	/* either the tty_lock() or the proc_list_lock() must be held */
3806 
3807 	if (tp->t_pgrp) {
3808 		pg = pg_ref(tp->t_pgrp);
3809 	}
3810 
3811 	return pg;
3812 }
3813 
3814 int
proc_transstart(proc_t p,int locked,int non_blocking)3815 proc_transstart(proc_t p, int locked, int non_blocking)
3816 {
3817 	if (locked == 0) {
3818 		proc_lock(p);
3819 	}
3820 	while ((p->p_lflag & P_LINTRANSIT) == P_LINTRANSIT) {
3821 		if (((p->p_lflag & P_LTRANSCOMMIT) == P_LTRANSCOMMIT) || non_blocking) {
3822 			if (locked == 0) {
3823 				proc_unlock(p);
3824 			}
3825 			return EDEADLK;
3826 		}
3827 		p->p_lflag |= P_LTRANSWAIT;
3828 		msleep(&p->p_lflag, &p->p_mlock, 0, "proc_signstart", NULL);
3829 	}
3830 	p->p_lflag |= P_LINTRANSIT;
3831 	p->p_transholder = current_thread();
3832 	if (locked == 0) {
3833 		proc_unlock(p);
3834 	}
3835 	return 0;
3836 }
3837 
3838 void
proc_transcommit(proc_t p,int locked)3839 proc_transcommit(proc_t p, int locked)
3840 {
3841 	if (locked == 0) {
3842 		proc_lock(p);
3843 	}
3844 
3845 	assert((p->p_lflag & P_LINTRANSIT) == P_LINTRANSIT);
3846 	assert(p->p_transholder == current_thread());
3847 	p->p_lflag |= P_LTRANSCOMMIT;
3848 
3849 	if ((p->p_lflag & P_LTRANSWAIT) == P_LTRANSWAIT) {
3850 		p->p_lflag &= ~P_LTRANSWAIT;
3851 		wakeup(&p->p_lflag);
3852 	}
3853 	if (locked == 0) {
3854 		proc_unlock(p);
3855 	}
3856 }
3857 
3858 void
proc_transend(proc_t p,int locked)3859 proc_transend(proc_t p, int locked)
3860 {
3861 	if (locked == 0) {
3862 		proc_lock(p);
3863 	}
3864 
3865 	p->p_lflag &= ~(P_LINTRANSIT | P_LTRANSCOMMIT);
3866 	p->p_transholder = NULL;
3867 
3868 	if ((p->p_lflag & P_LTRANSWAIT) == P_LTRANSWAIT) {
3869 		p->p_lflag &= ~P_LTRANSWAIT;
3870 		wakeup(&p->p_lflag);
3871 	}
3872 	if (locked == 0) {
3873 		proc_unlock(p);
3874 	}
3875 }
3876 
3877 int
proc_transwait(proc_t p,int locked)3878 proc_transwait(proc_t p, int locked)
3879 {
3880 	if (locked == 0) {
3881 		proc_lock(p);
3882 	}
3883 	while ((p->p_lflag & P_LINTRANSIT) == P_LINTRANSIT) {
3884 		if ((p->p_lflag & P_LTRANSCOMMIT) == P_LTRANSCOMMIT && current_proc() == p) {
3885 			if (locked == 0) {
3886 				proc_unlock(p);
3887 			}
3888 			return EDEADLK;
3889 		}
3890 		p->p_lflag |= P_LTRANSWAIT;
3891 		msleep(&p->p_lflag, &p->p_mlock, 0, "proc_signstart", NULL);
3892 	}
3893 	if (locked == 0) {
3894 		proc_unlock(p);
3895 	}
3896 	return 0;
3897 }
3898 
3899 void
proc_klist_lock(void)3900 proc_klist_lock(void)
3901 {
3902 	lck_mtx_lock(&proc_klist_mlock);
3903 }
3904 
3905 void
proc_klist_unlock(void)3906 proc_klist_unlock(void)
3907 {
3908 	lck_mtx_unlock(&proc_klist_mlock);
3909 }
3910 
3911 void
proc_knote(struct proc * p,long hint)3912 proc_knote(struct proc * p, long hint)
3913 {
3914 	proc_klist_lock();
3915 	KNOTE(&p->p_klist, hint);
3916 	proc_klist_unlock();
3917 }
3918 
3919 void
proc_knote_drain(struct proc * p)3920 proc_knote_drain(struct proc *p)
3921 {
3922 	struct knote *kn = NULL;
3923 
3924 	/*
3925 	 * Clear the proc's klist to avoid references after the proc is reaped.
3926 	 */
3927 	proc_klist_lock();
3928 	while ((kn = SLIST_FIRST(&p->p_klist))) {
3929 		kn->kn_proc = PROC_NULL;
3930 		KNOTE_DETACH(&p->p_klist, kn);
3931 	}
3932 	proc_klist_unlock();
3933 }
3934 
3935 void
proc_setregister(proc_t p)3936 proc_setregister(proc_t p)
3937 {
3938 	proc_lock(p);
3939 	p->p_lflag |= P_LREGISTER;
3940 	proc_unlock(p);
3941 }
3942 
3943 void
proc_resetregister(proc_t p)3944 proc_resetregister(proc_t p)
3945 {
3946 	proc_lock(p);
3947 	p->p_lflag &= ~P_LREGISTER;
3948 	proc_unlock(p);
3949 }
3950 
3951 bool
proc_get_pthread_jit_allowlist(proc_t p,bool * late_out)3952 proc_get_pthread_jit_allowlist(proc_t p, bool *late_out)
3953 {
3954 	bool ret = false;
3955 
3956 	proc_lock(p);
3957 	ret = (p->p_lflag & P_LPTHREADJITALLOWLIST);
3958 	*late_out = (p->p_lflag & P_LPTHREADJITFREEZELATE);
3959 	proc_unlock(p);
3960 
3961 	return ret;
3962 }
3963 
3964 void
proc_set_pthread_jit_allowlist(proc_t p,bool late)3965 proc_set_pthread_jit_allowlist(proc_t p, bool late)
3966 {
3967 	proc_lock(p);
3968 	p->p_lflag |= P_LPTHREADJITALLOWLIST;
3969 	if (late) {
3970 		p->p_lflag |= P_LPTHREADJITFREEZELATE;
3971 	}
3972 	proc_unlock(p);
3973 }
3974 
3975 pid_t
proc_pgrpid(proc_t p)3976 proc_pgrpid(proc_t p)
3977 {
3978 	return p->p_pgrpid;
3979 }
3980 
3981 pid_t
proc_sessionid(proc_t p)3982 proc_sessionid(proc_t p)
3983 {
3984 	return p->p_sessionid;
3985 }
3986 
3987 pid_t
proc_selfpgrpid()3988 proc_selfpgrpid()
3989 {
3990 	return current_proc()->p_pgrpid;
3991 }
3992 
3993 
3994 /* return control and action states */
3995 int
proc_getpcontrol(int pid,int * pcontrolp)3996 proc_getpcontrol(int pid, int * pcontrolp)
3997 {
3998 	proc_t p;
3999 
4000 	p = proc_find(pid);
4001 	if (p == PROC_NULL) {
4002 		return ESRCH;
4003 	}
4004 	if (pcontrolp != NULL) {
4005 		*pcontrolp = p->p_pcaction;
4006 	}
4007 
4008 	proc_rele(p);
4009 	return 0;
4010 }
4011 
4012 int
proc_dopcontrol(proc_t p)4013 proc_dopcontrol(proc_t p)
4014 {
4015 	int pcontrol;
4016 	os_reason_t kill_reason;
4017 
4018 	proc_lock(p);
4019 
4020 	pcontrol = PROC_CONTROL_STATE(p);
4021 
4022 	if (PROC_ACTION_STATE(p) == 0) {
4023 		switch (pcontrol) {
4024 		case P_PCTHROTTLE:
4025 			PROC_SETACTION_STATE(p);
4026 			proc_unlock(p);
4027 			printf("low swap: throttling pid %d (%s)\n", proc_getpid(p), p->p_comm);
4028 			break;
4029 
4030 		case P_PCSUSP:
4031 			PROC_SETACTION_STATE(p);
4032 			proc_unlock(p);
4033 			printf("low swap: suspending pid %d (%s)\n", proc_getpid(p), p->p_comm);
4034 			task_suspend(p->task);
4035 			break;
4036 
4037 		case P_PCKILL:
4038 			PROC_SETACTION_STATE(p);
4039 			proc_unlock(p);
4040 			printf("low swap: killing pid %d (%s)\n", proc_getpid(p), p->p_comm);
4041 			kill_reason = os_reason_create(OS_REASON_JETSAM, JETSAM_REASON_LOWSWAP);
4042 			psignal_with_reason(p, SIGKILL, kill_reason);
4043 			break;
4044 
4045 		default:
4046 			proc_unlock(p);
4047 		}
4048 	} else {
4049 		proc_unlock(p);
4050 	}
4051 
4052 	return PROC_RETURNED;
4053 }
4054 
4055 
4056 /*
4057  * Resume a throttled or suspended process.  This is an internal interface that's only
4058  * used by the user level code that presents the GUI when we run out of swap space and
4059  * hence is restricted to processes with superuser privileges.
4060  */
4061 
4062 int
proc_resetpcontrol(int pid)4063 proc_resetpcontrol(int pid)
4064 {
4065 	proc_t p;
4066 	int pcontrol;
4067 	int error;
4068 	proc_t self = current_proc();
4069 
4070 	/* if the process has been validated to handle resource control or root is valid one */
4071 	if (((self->p_lflag & P_LVMRSRCOWNER) == 0) && (error = suser(kauth_cred_get(), 0))) {
4072 		return error;
4073 	}
4074 
4075 	p = proc_find(pid);
4076 	if (p == PROC_NULL) {
4077 		return ESRCH;
4078 	}
4079 
4080 	proc_lock(p);
4081 
4082 	pcontrol = PROC_CONTROL_STATE(p);
4083 
4084 	if (PROC_ACTION_STATE(p) != 0) {
4085 		switch (pcontrol) {
4086 		case P_PCTHROTTLE:
4087 			PROC_RESETACTION_STATE(p);
4088 			proc_unlock(p);
4089 			printf("low swap: unthrottling pid %d (%s)\n", proc_getpid(p), p->p_comm);
4090 			break;
4091 
4092 		case P_PCSUSP:
4093 			PROC_RESETACTION_STATE(p);
4094 			proc_unlock(p);
4095 			printf("low swap: resuming pid %d (%s)\n", proc_getpid(p), p->p_comm);
4096 			task_resume(p->task);
4097 			break;
4098 
4099 		case P_PCKILL:
4100 			/* Huh? */
4101 			PROC_SETACTION_STATE(p);
4102 			proc_unlock(p);
4103 			printf("low swap: attempt to unkill pid %d (%s) ignored\n", proc_getpid(p), p->p_comm);
4104 			break;
4105 
4106 		default:
4107 			proc_unlock(p);
4108 		}
4109 	} else {
4110 		proc_unlock(p);
4111 	}
4112 
4113 	proc_rele(p);
4114 	return 0;
4115 }
4116 
4117 
4118 
4119 struct no_paging_space {
4120 	uint64_t        pcs_max_size;
4121 	uint64_t        pcs_uniqueid;
4122 	int             pcs_pid;
4123 	int             pcs_proc_count;
4124 	uint64_t        pcs_total_size;
4125 
4126 	uint64_t        npcs_max_size;
4127 	uint64_t        npcs_uniqueid;
4128 	int             npcs_pid;
4129 	int             npcs_proc_count;
4130 	uint64_t        npcs_total_size;
4131 
4132 	int             apcs_proc_count;
4133 	uint64_t        apcs_total_size;
4134 };
4135 
4136 
4137 static int
proc_pcontrol_filter(proc_t p,void * arg)4138 proc_pcontrol_filter(proc_t p, void *arg)
4139 {
4140 	struct no_paging_space *nps;
4141 	uint64_t        compressed;
4142 
4143 	nps = (struct no_paging_space *)arg;
4144 
4145 	compressed = get_task_compressed(p->task);
4146 
4147 	if (PROC_CONTROL_STATE(p)) {
4148 		if (PROC_ACTION_STATE(p) == 0) {
4149 			if (compressed > nps->pcs_max_size) {
4150 				nps->pcs_pid = proc_getpid(p);
4151 				nps->pcs_uniqueid = proc_uniqueid(p);
4152 				nps->pcs_max_size = compressed;
4153 			}
4154 			nps->pcs_total_size += compressed;
4155 			nps->pcs_proc_count++;
4156 		} else {
4157 			nps->apcs_total_size += compressed;
4158 			nps->apcs_proc_count++;
4159 		}
4160 	} else {
4161 		if (compressed > nps->npcs_max_size) {
4162 			nps->npcs_pid = proc_getpid(p);
4163 			nps->npcs_uniqueid = proc_uniqueid(p);
4164 			nps->npcs_max_size = compressed;
4165 		}
4166 		nps->npcs_total_size += compressed;
4167 		nps->npcs_proc_count++;
4168 	}
4169 	return 0;
4170 }
4171 
4172 
4173 static int
proc_pcontrol_null(__unused proc_t p,__unused void * arg)4174 proc_pcontrol_null(__unused proc_t p, __unused void *arg)
4175 {
4176 	return PROC_RETURNED;
4177 }
4178 
4179 
4180 /*
4181  * Deal with the low on compressor pool space condition... this function
4182  * gets called when we are approaching the limits of the compressor pool or
4183  * we are unable to create a new swap file.
4184  * Since this eventually creates a memory deadlock situtation, we need to take action to free up
4185  * memory resources (both compressed and uncompressed) in order to prevent the system from hanging completely.
4186  * There are 2 categories of processes to deal with.  Those that have an action
4187  * associated with them by the task itself and those that do not.  Actionable
4188  * tasks can have one of three categories specified:  ones that
4189  * can be killed immediately, ones that should be suspended, and ones that should
4190  * be throttled.  Processes that do not have an action associated with them are normally
4191  * ignored unless they are utilizing such a large percentage of the compressor pool (currently 50%)
4192  * that only by killing them can we hope to put the system back into a usable state.
4193  */
4194 
4195 #define NO_PAGING_SPACE_DEBUG   0
4196 
4197 extern uint64_t vm_compressor_pages_compressed(void);
4198 
4199 struct timeval  last_no_space_action = {.tv_sec = 0, .tv_usec = 0};
4200 
4201 #define MB_SIZE (1024 * 1024ULL)
4202 boolean_t       memorystatus_kill_on_VM_compressor_space_shortage(boolean_t);
4203 
4204 extern int32_t  max_kill_priority;
4205 
4206 int
no_paging_space_action()4207 no_paging_space_action()
4208 {
4209 	proc_t          p;
4210 	struct no_paging_space nps;
4211 	struct timeval  now;
4212 	os_reason_t kill_reason;
4213 
4214 	/*
4215 	 * Throttle how often we come through here.  Once every 5 seconds should be plenty.
4216 	 */
4217 	microtime(&now);
4218 
4219 	if (now.tv_sec <= last_no_space_action.tv_sec + 5) {
4220 		return 0;
4221 	}
4222 
4223 	/*
4224 	 * Examine all processes and find the biggest (biggest is based on the number of pages this
4225 	 * task has in the compressor pool) that has been marked to have some action
4226 	 * taken when swap space runs out... we also find the biggest that hasn't been marked for
4227 	 * action.
4228 	 *
4229 	 * If the biggest non-actionable task is over the "dangerously big" threashold (currently 50% of
4230 	 * the total number of pages held by the compressor, we go ahead and kill it since no other task
4231 	 * can have any real effect on the situation.  Otherwise, we go after the actionable process.
4232 	 */
4233 	bzero(&nps, sizeof(nps));
4234 
4235 	proc_iterate(PROC_ALLPROCLIST, proc_pcontrol_null, (void *)NULL, proc_pcontrol_filter, (void *)&nps);
4236 
4237 #if NO_PAGING_SPACE_DEBUG
4238 	printf("low swap: npcs_proc_count = %d, npcs_total_size = %qd, npcs_max_size = %qd\n",
4239 	    nps.npcs_proc_count, nps.npcs_total_size, nps.npcs_max_size);
4240 	printf("low swap: pcs_proc_count = %d, pcs_total_size = %qd, pcs_max_size = %qd\n",
4241 	    nps.pcs_proc_count, nps.pcs_total_size, nps.pcs_max_size);
4242 	printf("low swap: apcs_proc_count = %d, apcs_total_size = %qd\n",
4243 	    nps.apcs_proc_count, nps.apcs_total_size);
4244 #endif
4245 	if (nps.npcs_max_size > (vm_compressor_pages_compressed() * 50) / 100) {
4246 		/*
4247 		 * for now we'll knock out any task that has more then 50% of the pages
4248 		 * held by the compressor
4249 		 */
4250 		if ((p = proc_find(nps.npcs_pid)) != PROC_NULL) {
4251 			if (nps.npcs_uniqueid == proc_uniqueid(p)) {
4252 				/*
4253 				 * verify this is still the same process
4254 				 * in case the proc exited and the pid got reused while
4255 				 * we were finishing the proc_iterate and getting to this point
4256 				 */
4257 				last_no_space_action = now;
4258 
4259 				printf("low swap: killing largest compressed process with pid %d (%s) and size %llu MB\n", proc_getpid(p), p->p_comm, (nps.pcs_max_size / MB_SIZE));
4260 				kill_reason = os_reason_create(OS_REASON_JETSAM, JETSAM_REASON_LOWSWAP);
4261 				psignal_with_reason(p, SIGKILL, kill_reason);
4262 
4263 				proc_rele(p);
4264 
4265 				return 0;
4266 			}
4267 
4268 			proc_rele(p);
4269 		}
4270 	}
4271 
4272 	/*
4273 	 * We have some processes within our jetsam bands of consideration and hence can be killed.
4274 	 * So we will invoke the memorystatus thread to go ahead and kill something.
4275 	 */
4276 	if (memorystatus_get_proccnt_upto_priority(max_kill_priority) > 0) {
4277 		last_no_space_action = now;
4278 		memorystatus_kill_on_VM_compressor_space_shortage(TRUE /* async */);
4279 		return 1;
4280 	}
4281 
4282 	/*
4283 	 * No eligible processes to kill. So let's suspend/kill the largest
4284 	 * process depending on its policy control specifications.
4285 	 */
4286 
4287 	if (nps.pcs_max_size > 0) {
4288 		if ((p = proc_find(nps.pcs_pid)) != PROC_NULL) {
4289 			if (nps.pcs_uniqueid == proc_uniqueid(p)) {
4290 				/*
4291 				 * verify this is still the same process
4292 				 * in case the proc exited and the pid got reused while
4293 				 * we were finishing the proc_iterate and getting to this point
4294 				 */
4295 				last_no_space_action = now;
4296 
4297 				proc_dopcontrol(p);
4298 
4299 				proc_rele(p);
4300 
4301 				return 1;
4302 			}
4303 
4304 			proc_rele(p);
4305 		}
4306 	}
4307 	last_no_space_action = now;
4308 
4309 	printf("low swap: unable to find any eligible processes to take action on\n");
4310 
4311 	return 0;
4312 }
4313 
4314 int
proc_trace_log(__unused proc_t p,struct proc_trace_log_args * uap,__unused int * retval)4315 proc_trace_log(__unused proc_t p, struct proc_trace_log_args *uap, __unused int *retval)
4316 {
4317 	int ret = 0;
4318 	proc_t target_proc = PROC_NULL;
4319 	pid_t target_pid = uap->pid;
4320 	uint64_t target_uniqueid = uap->uniqueid;
4321 	task_t target_task = NULL;
4322 
4323 	if (priv_check_cred(kauth_cred_get(), PRIV_PROC_TRACE_INSPECT, 0)) {
4324 		ret = EPERM;
4325 		goto out;
4326 	}
4327 	target_proc = proc_find(target_pid);
4328 	if (target_proc != PROC_NULL) {
4329 		if (target_uniqueid != proc_uniqueid(target_proc)) {
4330 			ret = ENOENT;
4331 			goto out;
4332 		}
4333 
4334 		target_task = proc_task(target_proc);
4335 		if (task_send_trace_memory(target_task, target_pid, target_uniqueid)) {
4336 			ret = EINVAL;
4337 			goto out;
4338 		}
4339 	} else {
4340 		ret = ENOENT;
4341 	}
4342 
4343 out:
4344 	if (target_proc != PROC_NULL) {
4345 		proc_rele(target_proc);
4346 	}
4347 	return ret;
4348 }
4349 
4350 #if VM_SCAN_FOR_SHADOW_CHAIN
4351 extern int vm_map_shadow_max(vm_map_t map);
4352 int proc_shadow_max(void);
4353 int
proc_shadow_max(void)4354 proc_shadow_max(void)
4355 {
4356 	int             retval, max;
4357 	proc_t          p;
4358 	task_t          task;
4359 	vm_map_t        map;
4360 
4361 	max = 0;
4362 	proc_list_lock();
4363 	for (p = allproc.lh_first; (p != 0); p = p->p_list.le_next) {
4364 		if (p->p_stat == SIDL) {
4365 			continue;
4366 		}
4367 		task = p->task;
4368 		if (task == NULL) {
4369 			continue;
4370 		}
4371 		map = get_task_map(task);
4372 		if (map == NULL) {
4373 			continue;
4374 		}
4375 		retval = vm_map_shadow_max(map);
4376 		if (retval > max) {
4377 			max = retval;
4378 		}
4379 	}
4380 	proc_list_unlock();
4381 	return max;
4382 }
4383 #endif /* VM_SCAN_FOR_SHADOW_CHAIN */
4384 
4385 void proc_set_responsible_pid(proc_t target_proc, pid_t responsible_pid);
4386 void
proc_set_responsible_pid(proc_t target_proc,pid_t responsible_pid)4387 proc_set_responsible_pid(proc_t target_proc, pid_t responsible_pid)
4388 {
4389 	if (target_proc != NULL) {
4390 		target_proc->p_responsible_pid = responsible_pid;
4391 	}
4392 	return;
4393 }
4394 
4395 int
proc_chrooted(proc_t p)4396 proc_chrooted(proc_t p)
4397 {
4398 	int retval = 0;
4399 
4400 	if (p) {
4401 		proc_fdlock(p);
4402 		retval = (p->p_fd.fd_rdir != NULL) ? 1 : 0;
4403 		proc_fdunlock(p);
4404 	}
4405 
4406 	return retval;
4407 }
4408 
4409 boolean_t
proc_send_synchronous_EXC_RESOURCE(proc_t p)4410 proc_send_synchronous_EXC_RESOURCE(proc_t p)
4411 {
4412 	if (p == PROC_NULL) {
4413 		return FALSE;
4414 	}
4415 
4416 	/* Send sync EXC_RESOURCE if the process is traced */
4417 	if (ISSET(p->p_lflag, P_LTRACED)) {
4418 		return TRUE;
4419 	}
4420 	return FALSE;
4421 }
4422 
4423 #if CONFIG_MACF
4424 size_t
proc_get_syscall_filter_mask_size(int which)4425 proc_get_syscall_filter_mask_size(int which)
4426 {
4427 	switch (which) {
4428 	case SYSCALL_MASK_UNIX:
4429 		return nsysent;
4430 	case SYSCALL_MASK_MACH:
4431 		return mach_trap_count;
4432 	case SYSCALL_MASK_KOBJ:
4433 		return mach_kobj_count;
4434 	default:
4435 		return 0;
4436 	}
4437 }
4438 
4439 int
proc_set_syscall_filter_mask(proc_t p,int which,unsigned char * maskptr,size_t masklen)4440 proc_set_syscall_filter_mask(proc_t p, int which, unsigned char *maskptr, size_t masklen)
4441 {
4442 #if DEVELOPMENT || DEBUG
4443 	if (syscallfilter_disable) {
4444 		printf("proc_set_syscall_filter_mask: attempt to set policy for pid %d, but disabled by boot-arg\n", proc_pid(p));
4445 		return 0;
4446 	}
4447 #endif // DEVELOPMENT || DEBUG
4448 
4449 	switch (which) {
4450 	case SYSCALL_MASK_UNIX:
4451 		if (maskptr != NULL && masklen != nsysent) {
4452 			return EINVAL;
4453 		}
4454 		proc_syscall_filter_mask_set(p, maskptr);
4455 		break;
4456 	case SYSCALL_MASK_MACH:
4457 		if (maskptr != NULL && masklen != (size_t)mach_trap_count) {
4458 			return EINVAL;
4459 		}
4460 		mac_task_set_mach_filter_mask(p->task, maskptr);
4461 		break;
4462 	case SYSCALL_MASK_KOBJ:
4463 		if (maskptr != NULL && masklen != (size_t)mach_kobj_count) {
4464 			return EINVAL;
4465 		}
4466 		mac_task_set_kobj_filter_mask(p->task, maskptr);
4467 		break;
4468 	default:
4469 		return EINVAL;
4470 	}
4471 
4472 	return 0;
4473 }
4474 
4475 int
proc_set_syscall_filter_callbacks(syscall_filter_cbs_t cbs)4476 proc_set_syscall_filter_callbacks(syscall_filter_cbs_t cbs)
4477 {
4478 	if (cbs->version != SYSCALL_FILTER_CALLBACK_VERSION) {
4479 		return EINVAL;
4480 	}
4481 
4482 	/* XXX register unix filter callback instead of using MACF hook. */
4483 
4484 	if (cbs->mach_filter_cbfunc || cbs->kobj_filter_cbfunc) {
4485 		if (mac_task_register_filter_callbacks(cbs->mach_filter_cbfunc,
4486 		    cbs->kobj_filter_cbfunc) != 0) {
4487 			return EPERM;
4488 		}
4489 	}
4490 
4491 	return 0;
4492 }
4493 
4494 int
proc_set_syscall_filter_index(int which,int num,int index)4495 proc_set_syscall_filter_index(int which, int num, int index)
4496 {
4497 	switch (which) {
4498 	case SYSCALL_MASK_KOBJ:
4499 		if (ipc_kobject_set_kobjidx(num, index) != 0) {
4500 			return ENOENT;
4501 		}
4502 		break;
4503 	default:
4504 		return EINVAL;
4505 	}
4506 
4507 	return 0;
4508 }
4509 #endif /* CONFIG_MACF */
4510 
4511 int
proc_set_filter_message_flag(proc_t p,boolean_t flag)4512 proc_set_filter_message_flag(proc_t p, boolean_t flag)
4513 {
4514 	if (p == PROC_NULL) {
4515 		return EINVAL;
4516 	}
4517 
4518 	task_set_filter_msg_flag(proc_task(p), flag);
4519 
4520 	return 0;
4521 }
4522 
4523 int
proc_get_filter_message_flag(proc_t p,boolean_t * flag)4524 proc_get_filter_message_flag(proc_t p, boolean_t *flag)
4525 {
4526 	if (p == PROC_NULL || flag == NULL) {
4527 		return EINVAL;
4528 	}
4529 
4530 	*flag = task_get_filter_msg_flag(proc_task(p));
4531 
4532 	return 0;
4533 }
4534 
4535 bool
proc_is_traced(proc_t p)4536 proc_is_traced(proc_t p)
4537 {
4538 	bool ret = FALSE;
4539 	assert(p != PROC_NULL);
4540 	proc_lock(p);
4541 	if (p->p_lflag & P_LTRACED) {
4542 		ret = TRUE;
4543 	}
4544 	proc_unlock(p);
4545 	return ret;
4546 }
4547 
4548 #ifdef CONFIG_32BIT_TELEMETRY
4549 void
proc_log_32bit_telemetry(proc_t p)4550 proc_log_32bit_telemetry(proc_t p)
4551 {
4552 	/* Gather info */
4553 	char signature_buf[MAX_32BIT_EXEC_SIG_SIZE] = { 0 };
4554 	char * signature_cur_end = &signature_buf[0];
4555 	char * signature_buf_end = &signature_buf[MAX_32BIT_EXEC_SIG_SIZE - 1];
4556 	int bytes_printed = 0;
4557 
4558 	const char * teamid = NULL;
4559 	const char * identity = NULL;
4560 	struct cs_blob * csblob = NULL;
4561 
4562 	proc_list_lock();
4563 
4564 	/*
4565 	 * Get proc name and parent proc name; if the parent execs, we'll get a
4566 	 * garbled name.
4567 	 */
4568 	bytes_printed = scnprintf(signature_cur_end,
4569 	    signature_buf_end - signature_cur_end,
4570 	    "%s,%s,", p->p_name,
4571 	    (p->p_pptr ? p->p_pptr->p_name : ""));
4572 
4573 	if (bytes_printed > 0) {
4574 		signature_cur_end += bytes_printed;
4575 	}
4576 
4577 	proc_list_unlock();
4578 
4579 	/* Get developer info. */
4580 	vnode_t v = proc_getexecutablevnode(p);
4581 
4582 	if (v) {
4583 		csblob = csvnode_get_blob(v, 0);
4584 
4585 		if (csblob) {
4586 			teamid = csblob_get_teamid(csblob);
4587 			identity = csblob_get_identity(csblob);
4588 		}
4589 	}
4590 
4591 	if (teamid == NULL) {
4592 		teamid = "";
4593 	}
4594 
4595 	if (identity == NULL) {
4596 		identity = "";
4597 	}
4598 
4599 	bytes_printed = scnprintf(signature_cur_end,
4600 	    signature_buf_end - signature_cur_end,
4601 	    "%s,%s", teamid, identity);
4602 
4603 	if (bytes_printed > 0) {
4604 		signature_cur_end += bytes_printed;
4605 	}
4606 
4607 	if (v) {
4608 		vnode_put(v);
4609 	}
4610 
4611 	/*
4612 	 * We may want to rate limit here, although the SUMMARIZE key should
4613 	 * help us aggregate events in userspace.
4614 	 */
4615 
4616 	/* Emit log */
4617 	kern_asl_msg(LOG_DEBUG, "messagetracer", 3,
4618 	    /* 0 */ "com.apple.message.domain", "com.apple.kernel.32bit_exec",
4619 	    /* 1 */ "com.apple.message.signature", signature_buf,
4620 	    /* 2 */ "com.apple.message.summarize", "YES",
4621 	    NULL);
4622 }
4623 #endif /* CONFIG_32BIT_TELEMETRY */
4624 
4625 #if CONFIG_PROC_RESOURCE_LIMITS
4626 int
proc_set_filedesc_limits(proc_t p,int soft_limit,int hard_limit)4627 proc_set_filedesc_limits(proc_t p, int soft_limit, int hard_limit)
4628 {
4629 	struct filedesc *fdp = &p->p_fd;
4630 	int retval = 0;
4631 
4632 	proc_fdlock(p);
4633 
4634 	if (hard_limit > 0) {
4635 		if (soft_limit >= hard_limit) {
4636 			soft_limit = 0;
4637 		}
4638 	}
4639 	fdp->fd_nfiles_soft_limit = soft_limit;
4640 	fdp->fd_nfiles_hard_limit = hard_limit;
4641 	/* Make sure that current fd_nfiles hasn't already exceeded these limits */
4642 	fd_check_limit_exceeded(fdp);
4643 
4644 	proc_fdunlock(p);
4645 
4646 	return retval;
4647 }
4648 #endif /* CONFIG_PROC_RESOURCE_LIMITS */
4649 
4650 void
proc_filedesc_ast(__unused task_t task)4651 proc_filedesc_ast(__unused task_t task)
4652 {
4653 #if CONFIG_PROC_RESOURCE_LIMITS
4654 	int current_size, soft_limit, hard_limit;
4655 	assert(task == current_task());
4656 	proc_t p = get_bsdtask_info(task);
4657 	struct filedesc *fdp = &p->p_fd;
4658 
4659 	proc_fdlock(p);
4660 	current_size = fdp->fd_nfiles_open;
4661 	hard_limit = fdp->fd_nfiles_hard_limit;
4662 	soft_limit = fdp->fd_nfiles_soft_limit;
4663 
4664 	/*
4665 	 * Check if the thread sending the soft limit notification arrives after
4666 	 * the one that sent the hard limit notification
4667 	 */
4668 
4669 	if (hard_limit > 0 && current_size >= hard_limit) {
4670 		if (fd_hard_limit_already_notified(fdp)) {
4671 			soft_limit = hard_limit = 0;
4672 		} else {
4673 			fd_hard_limit_notified(fdp);
4674 			soft_limit = 0;
4675 		}
4676 	} else if (soft_limit > 0 && current_size >= soft_limit) {
4677 		if (fd_soft_limit_already_notified(fdp)) {
4678 			soft_limit = hard_limit = 0;
4679 		} else {
4680 			fd_soft_limit_notified(fdp);
4681 			hard_limit = 0;
4682 		}
4683 	}
4684 
4685 	proc_fdunlock(p);
4686 
4687 	if (hard_limit || soft_limit) {
4688 		task_filedesc_ast(task, current_size, soft_limit, hard_limit);
4689 	}
4690 #endif /* CONFIG_PROC_RESOURCE_LIMITS */
4691 }
4692 
4693 proc_ro_t
proc_ro_alloc(proc_t p,proc_ro_data_t p_data,task_t t,task_ro_data_t t_data)4694 proc_ro_alloc(proc_t p, proc_ro_data_t p_data, task_t t, task_ro_data_t t_data)
4695 {
4696 	proc_ro_t pr;
4697 	struct proc_ro pr_local = {};
4698 
4699 	pr = (proc_ro_t)zalloc_ro(ZONE_ID_PROC_RO, Z_WAITOK | Z_NOFAIL | Z_ZERO);
4700 
4701 	if (p != PROC_NULL) {
4702 		pr_local.pr_proc = p;
4703 		pr_local.proc_data = *p_data;
4704 	}
4705 
4706 	if (t != TASK_NULL) {
4707 		pr_local.pr_task = t;
4708 		pr_local.task_data = *t_data;
4709 	}
4710 
4711 	if ((p != PROC_NULL) || (t != TASK_NULL)) {
4712 		zalloc_ro_update_elem(ZONE_ID_PROC_RO, pr, &pr_local);
4713 	}
4714 
4715 	return pr;
4716 }
4717 
4718 void
proc_ro_free(proc_ro_t pr)4719 proc_ro_free(proc_ro_t pr)
4720 {
4721 	zfree_ro(ZONE_ID_PROC_RO, pr);
4722 }
4723 
4724 static proc_ro_t
proc_ro_ref_proc(proc_ro_t pr,proc_t p,proc_ro_data_t p_data)4725 proc_ro_ref_proc(proc_ro_t pr, proc_t p, proc_ro_data_t p_data)
4726 {
4727 	struct proc_ro pr_local;
4728 
4729 	if (pr->pr_proc != PROC_NULL) {
4730 		panic("%s: proc_ro already has an owning proc", __func__);
4731 	}
4732 
4733 	pr_local = *pr;
4734 	pr_local.pr_proc = p;
4735 	pr_local.proc_data = *p_data;
4736 
4737 	/* make sure readers of the proc_ro always see initialized data */
4738 	os_atomic_thread_fence(release);
4739 	zalloc_ro_update_elem(ZONE_ID_PROC_RO, pr, &pr_local);
4740 
4741 	return pr;
4742 }
4743 
4744 proc_ro_t
proc_ro_ref_task(proc_ro_t pr,task_t t,task_ro_data_t t_data)4745 proc_ro_ref_task(proc_ro_t pr, task_t t, task_ro_data_t t_data)
4746 {
4747 	struct proc_ro pr_local;
4748 
4749 	if (pr->pr_task != TASK_NULL) {
4750 		panic("%s: proc_ro already has an owning task", __func__);
4751 	}
4752 
4753 	pr_local = *pr;
4754 	pr_local.pr_task = t;
4755 	pr_local.task_data = *t_data;
4756 
4757 	zalloc_ro_update_elem(ZONE_ID_PROC_RO, pr, &pr_local);
4758 
4759 	return pr;
4760 }
4761 
4762 void
proc_switch_ro(proc_t p,proc_ro_t new_ro)4763 proc_switch_ro(proc_t p, proc_ro_t new_ro)
4764 {
4765 	proc_ro_t old_ro;
4766 
4767 	proc_list_lock();
4768 
4769 	old_ro = p->p_proc_ro;
4770 
4771 	p->p_proc_ro = proc_ro_ref_proc(new_ro, p, &old_ro->proc_data);
4772 	old_ro = proc_ro_release_proc(old_ro);
4773 
4774 	if (old_ro != NULL) {
4775 		proc_ro_free(old_ro);
4776 	}
4777 
4778 	proc_list_unlock();
4779 }
4780 
4781 proc_ro_t
proc_ro_release_proc(proc_ro_t pr)4782 proc_ro_release_proc(proc_ro_t pr)
4783 {
4784 	/*
4785 	 * No need to take a lock in here: when called in the racy case
4786 	 * (reap_child_locked vs task_deallocate_internal), the proc list is
4787 	 * already held.  All other callsites are not racy.
4788 	 */
4789 	if (pr->pr_task == TASK_NULL) {
4790 		/* We're dropping the last ref. */
4791 		return pr;
4792 	} else if (pr->pr_proc != PROC_NULL) {
4793 		/* Task still has a ref, so just clear the proc owner. */
4794 		zalloc_ro_clear_field(ZONE_ID_PROC_RO, pr, pr_proc);
4795 	}
4796 
4797 	return NULL;
4798 }
4799 
4800 proc_ro_t
proc_ro_release_task(proc_ro_t pr)4801 proc_ro_release_task(proc_ro_t pr)
4802 {
4803 	/*
4804 	 * We take the proc list here to avoid a race between a child proc being
4805 	 * reaped and the associated task being deallocated.
4806 	 *
4807 	 * This function is only ever called in the racy case
4808 	 * (task_deallocate_internal), so we always take the lock.
4809 	 */
4810 	proc_list_lock();
4811 
4812 	if (pr->pr_proc == PROC_NULL) {
4813 		/* We're dropping the last ref. */
4814 		proc_list_unlock();
4815 		return pr;
4816 	} else if (pr->pr_task != TASK_NULL) {
4817 		/* Proc still has a ref, so just clear the task owner. */
4818 		zalloc_ro_clear_field(ZONE_ID_PROC_RO, pr, pr_task);
4819 	}
4820 
4821 	proc_list_unlock();
4822 	return NULL;
4823 }
4824 
4825 __abortlike
4826 static void
panic_proc_ro_proc_backref_mismatch(proc_t p,proc_ro_t ro)4827 panic_proc_ro_proc_backref_mismatch(proc_t p, proc_ro_t ro)
4828 {
4829 	panic("proc_ro->proc backref mismatch: p=%p, ro=%p, "
4830 	    "proc_ro_proc(ro)=%p", p, ro, proc_ro_proc(ro));
4831 }
4832 
4833 proc_ro_t
proc_get_ro(proc_t p)4834 proc_get_ro(proc_t p)
4835 {
4836 	proc_ro_t ro = p->p_proc_ro;
4837 
4838 	zone_require_ro(ZONE_ID_PROC_RO, sizeof(struct proc_ro), ro);
4839 	if (__improbable(proc_ro_proc(ro) != p)) {
4840 		panic_proc_ro_proc_backref_mismatch(p, ro);
4841 	}
4842 
4843 	return ro;
4844 }
4845 
4846 proc_ro_t
current_proc_ro(void)4847 current_proc_ro(void)
4848 {
4849 	if (__improbable(current_thread_ro()->tro_proc == NULL)) {
4850 		return kernproc->p_proc_ro;
4851 	}
4852 
4853 	return current_thread_ro()->tro_proc_ro;
4854 }
4855 
4856 proc_t
proc_ro_proc(proc_ro_t pr)4857 proc_ro_proc(proc_ro_t pr)
4858 {
4859 	return pr->pr_proc;
4860 }
4861 
4862 task_t
proc_ro_task(proc_ro_t pr)4863 proc_ro_task(proc_ro_t pr)
4864 {
4865 	return pr->pr_task;
4866 }
4867