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