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