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