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