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