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