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