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