2 * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
28 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
30 * Copyright (c) 1982, 1986, 1989, 1991, 1993
31 * The Regents of the University of California. All rights reserved.
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
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.
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
61 * @(#)kern_proc.c 8.4 (Berkeley) 1/4/94
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,
70 * 04-Aug-97 Umesh Vaishampayan (umeshv@apple.com)
71 * Added current_proc_EXTERNAL() function for the use of kernel
74 * 05-Jun-95 Mac Gillon (mgillon) at NeXT
75 * New version based on 3.3NS and 4.4
79 #include <sys/param.h>
80 #include <sys/systm.h>
81 #include <sys/kernel.h>
82 #include <sys/proc_internal.h>
85 #include <sys/file_internal.h>
87 #include <sys/malloc.h>
90 #include <sys/ioctl.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 <kern/kalloc.h>
100 #include <kern/task.h>
101 #include <kern/assert.h>
102 #include <vm/vm_protos.h>
103 #include <vm/vm_map.h> /* vm_map_switch_protect() */
104 #include <mach/task.h>
107 #include <security/mac_framework.h>
110 #include <libkern/crypto/sha1.h>
113 * Structure associated with user cacheing.
116 LIST_ENTRY(uidinfo
) ui_hash
;
120 #define UIHASH(uid) (&uihashtbl[(uid) & uihash])
121 LIST_HEAD(uihashhead
, uidinfo
) *uihashtbl
;
122 u_long uihash
; /* size of hash table - 1 */
125 * Other process lists
127 struct pidhashhead
*pidhashtbl
;
129 struct pgrphashhead
*pgrphashtbl
;
131 struct sesshashhead
*sesshashtbl
;
134 struct proclist allproc
;
135 struct proclist zombproc
;
136 extern struct tty cons
;
142 static pid_t lastlcid
= 1;
143 static int alllctx_cnt
;
145 #define LCID_MAX 8192 /* Does this really need to be large? */
146 static int maxlcid
= LCID_MAX
;
148 LIST_HEAD(lctxlist
, lctx
);
149 static struct lctxlist alllctx
;
151 lck_mtx_t alllctx_lock
;
152 lck_grp_t
* lctx_lck_grp
;
153 lck_grp_attr_t
* lctx_lck_grp_attr
;
154 lck_attr_t
* lctx_lck_attr
;
156 static void lctxinit(void);
160 #define __PROC_INTERNAL_DEBUG 1
162 /* Name to give to core files */
163 __private_extern__
char corefilename
[MAXPATHLEN
+1] = {"/cores/core.%P"};
165 static void orphanpg(struct pgrp
*pg
);
166 void proc_name_kdp(task_t t
, char * buf
, int size
);
167 char *proc_name_address(void *p
);
169 static proc_t
proc_refinternal_locked(proc_t p
);
170 static void pgrp_add(struct pgrp
* pgrp
, proc_t parent
, proc_t child
);
171 static void pgrp_remove(proc_t p
);
172 static void pgrp_replace(proc_t p
, struct pgrp
*pgrp
);
173 static void pgdelete_dropref(struct pgrp
*pgrp
);
174 static proc_t
proc_find_zombref(int pid
);
175 static void proc_drop_zombref(proc_t p
);
176 extern void pg_rele_dropref(struct pgrp
* pgrp
);
178 struct fixjob_iterargs
{
180 struct session
* mysession
;
184 int fixjob_callback(proc_t
, void *);
187 * Initialize global process hashing structures.
193 LIST_INIT(&zombproc
);
194 pidhashtbl
= hashinit(maxproc
/ 4, M_PROC
, &pidhash
);
195 pgrphashtbl
= hashinit(maxproc
/ 4, M_PROC
, &pgrphash
);
196 sesshashtbl
= hashinit(maxproc
/ 4, M_PROC
, &sesshash
);
197 uihashtbl
= hashinit(maxproc
/ 16, M_PROC
, &uihash
);
204 * Change the count associated with number of processes
205 * a given user is using. This routine protects the uihash
209 chgproccnt(uid_t uid
, int diff
)
212 struct uidinfo
*newuip
= NULL
;
213 struct uihashhead
*uipp
;
219 for (uip
= uipp
->lh_first
; uip
!= 0; uip
= uip
->ui_hash
.le_next
)
220 if (uip
->ui_uid
== uid
)
223 uip
->ui_proccnt
+= diff
;
224 if (uip
->ui_proccnt
> 0) {
225 retval
= uip
->ui_proccnt
;
229 if (uip
->ui_proccnt
< 0)
230 panic("chgproccnt: procs < 0");
231 LIST_REMOVE(uip
, ui_hash
);
234 FREE_ZONE(uip
, sizeof(*uip
), M_PROC
);
243 panic("chgproccnt: lost user");
245 if (newuip
!= NULL
) {
248 LIST_INSERT_HEAD(uipp
, uip
, ui_hash
);
250 uip
->ui_proccnt
= diff
;
256 MALLOC_ZONE(newuip
, struct uidinfo
*, sizeof(*uip
), M_PROC
, M_WAITOK
);
258 panic("chgproccnt: M_PROC zone depleted");
262 FREE_ZONE(newuip
, sizeof(*uip
), M_PROC
);
267 * Is p an inferior of the current process?
275 for (; p
!= current_proc(); p
= p
->p_pptr
)
285 * Is p an inferior of t ?
288 isinferior(proc_t p
, proc_t t
)
294 /* if p==t they are not inferior */
299 for (; p
!= t
; p
= p
->p_pptr
) {
302 /* Detect here if we're in a cycle */
303 if ((p
->p_pid
== 0) || (p
->p_pptr
== start
) || (nchecked
>= nprocs
))
313 proc_isinferior(int pid1
, int pid2
)
315 proc_t p
= PROC_NULL
;
316 proc_t t
= PROC_NULL
;
319 if (((p
= proc_find(pid1
)) != (proc_t
)0 ) && ((t
= proc_find(pid2
)) != (proc_t
)0))
320 retval
= isinferior(p
, t
);
333 return(proc_findinternal(pid
, 0));
337 proc_findinternal(int pid
, int locked
)
339 proc_t p
= PROC_NULL
;
345 p
= pfind_locked(pid
);
346 if ((p
== PROC_NULL
) || (p
!= proc_refinternal_locked(p
)))
374 if (p
!= proc_refinternal_locked(p
))
382 proc_refinternal_locked(proc_t p
)
386 /* if process still in creation return failure */
387 if ((p
== PROC_NULL
) || ((p
->p_listflag
& P_LIST_INCREATE
) != 0))
389 /* do not return process marked for termination */
390 if ((p
->p_stat
!= SZOMB
) && ((p
->p_listflag
& P_LIST_EXITED
) == 0) && ((p
->p_listflag
& (P_LIST_DRAINWAIT
| P_LIST_DRAIN
| P_LIST_DEAD
)) == 0))
399 proc_rele_locked(proc_t p
)
402 if (p
->p_refcount
> 0) {
404 if ((p
->p_refcount
== 0) && ((p
->p_listflag
& P_LIST_DRAINWAIT
) == P_LIST_DRAINWAIT
)) {
405 p
->p_listflag
&= ~P_LIST_DRAINWAIT
;
406 wakeup(&p
->p_refcount
);
409 panic("proc_rele_locked -ve ref\n");
414 proc_find_zombref(int pid
)
416 proc_t p1
= PROC_NULL
;
417 proc_t p
= PROC_NULL
;
421 p
= pfind_locked(pid
);
423 /* if process still in creation return NULL */
424 if ((p
== PROC_NULL
) || ((p
->p_listflag
& P_LIST_INCREATE
) != 0)) {
429 /* if process has not started exit or is being reaped, return NULL */
430 if (((p
->p_listflag
& P_LIST_EXITED
) != 0) && ((p
->p_listflag
& P_LIST_WAITING
) == 0)) {
431 p
->p_listflag
|= P_LIST_WAITING
;
442 proc_drop_zombref(proc_t p
)
445 if ((p
->p_listflag
& P_LIST_WAITING
) == P_LIST_WAITING
) {
446 p
->p_listflag
&= ~P_LIST_WAITING
;
454 proc_refdrain(proc_t p
)
459 p
->p_listflag
|= P_LIST_DRAIN
;
460 while (p
->p_refcount
) {
461 p
->p_listflag
|= P_LIST_DRAINWAIT
;
462 msleep(&p
->p_refcount
, proc_list_mlock
, 0, "proc_refdrain", 0) ;
464 p
->p_listflag
&= ~P_LIST_DRAIN
;
465 p
->p_listflag
|= P_LIST_DEAD
;
473 proc_parentholdref(proc_t p
)
475 proc_t parent
= PROC_NULL
;
483 if ((pp
== PROC_NULL
) || (pp
->p_stat
== SZOMB
) || ((pp
->p_listflag
& (P_LIST_CHILDDRSTART
| P_LIST_CHILDDRAINED
)) == (P_LIST_CHILDDRSTART
| P_LIST_CHILDDRAINED
))) {
488 if ((pp
->p_listflag
& (P_LIST_CHILDDRSTART
| P_LIST_CHILDDRAINED
)) == P_LIST_CHILDDRSTART
) {
489 pp
->p_listflag
|= P_LIST_CHILDDRWAIT
;
490 msleep(&pp
->p_childrencnt
, proc_list_mlock
, 0, "proc_parent", 0);
499 if ((pp
->p_listflag
& (P_LIST_CHILDDRSTART
| P_LIST_CHILDDRAINED
)) == 0) {
510 proc_parentdropref(proc_t p
, int listlocked
)
515 if (p
->p_parentref
> 0) {
517 if ((p
->p_parentref
== 0) && ((p
->p_listflag
& P_LIST_PARENTREFWAIT
) == P_LIST_PARENTREFWAIT
)) {
518 p
->p_listflag
&= ~P_LIST_PARENTREFWAIT
;
519 wakeup(&p
->p_parentref
);
522 panic("proc_parentdropref -ve ref\n");
530 proc_childdrainstart(proc_t p
)
532 #if __PROC_INTERNAL_DEBUG
533 if ((p
->p_listflag
& P_LIST_CHILDDRSTART
) == P_LIST_CHILDDRSTART
)
534 panic("proc_childdrainstart: childdrain already started\n");
536 p
->p_listflag
|= P_LIST_CHILDDRSTART
;
537 /* wait for all that hold parentrefs to drop */
538 while (p
->p_parentref
> 0) {
539 p
->p_listflag
|= P_LIST_PARENTREFWAIT
;
540 msleep(&p
->p_parentref
, proc_list_mlock
, 0, "proc_childdrainstart", 0) ;
546 proc_childdrainend(proc_t p
)
548 #if __PROC_INTERNAL_DEBUG
549 if (p
->p_childrencnt
> 0)
550 panic("exiting: children stil hanging around\n");
552 p
->p_listflag
|= P_LIST_CHILDDRAINED
;
553 if ((p
->p_listflag
& (P_LIST_CHILDLKWAIT
|P_LIST_CHILDDRWAIT
)) != 0) {
554 p
->p_listflag
&= ~(P_LIST_CHILDLKWAIT
|P_LIST_CHILDDRWAIT
);
555 wakeup(&p
->p_childrencnt
);
560 proc_checkdeadrefs(__unused proc_t p
)
562 #if __PROC_INTERNAL_DEBUG
563 if ((p
->p_listflag
& P_LIST_INHASH
) != 0)
564 panic("proc being freed and still in hash %p: %u\n", p
, p
->p_listflag
);
565 if (p
->p_childrencnt
!= 0)
566 panic("proc being freed and pending children cnt %p:%d\n", p
, p
->p_childrencnt
);
567 if (p
->p_refcount
!= 0)
568 panic("proc being freed and pending refcount %p:%d\n", p
, p
->p_refcount
);
569 if (p
->p_parentref
!= 0)
570 panic("proc being freed and pending parentrefs %p:%d\n", p
, p
->p_parentref
);
589 proc_t p
= current_proc();
596 proc_t p
= current_proc();
601 proc_parent(proc_t p
)
609 parent
= proc_refinternal_locked(pp
);
610 if ((parent
== PROC_NULL
) && (pp
!= PROC_NULL
) && (pp
->p_stat
!= SZOMB
) && ((pp
->p_listflag
& P_LIST_EXITED
) != 0) && ((pp
->p_listflag
& P_LIST_CHILDDRAINED
)== 0)){
611 pp
->p_listflag
|= P_LIST_CHILDLKWAIT
;
612 msleep(&pp
->p_childrencnt
, proc_list_mlock
, 0, "proc_parent", 0);
621 proc_name(int pid
, char * buf
, int size
)
625 if ((p
= proc_find(pid
)) != PROC_NULL
) {
626 strlcpy(buf
, &p
->p_comm
[0], size
);
632 proc_name_kdp(task_t t
, char * buf
, int size
)
634 proc_t p
= get_bsdtask_info(t
);
637 strlcpy(buf
, &p
->p_comm
[0], size
);
641 proc_name_address(void *p
)
643 return &((proc_t
)p
)->p_comm
[0];
647 proc_selfname(char * buf
, int size
)
651 if ((p
= current_proc())!= (proc_t
)0) {
652 strlcpy(buf
, &p
->p_comm
[0], size
);
657 proc_signal(int pid
, int signum
)
661 if ((p
= proc_find(pid
)) != PROC_NULL
) {
668 proc_issignal(int pid
, sigset_t mask
)
673 if ((p
= proc_find(pid
)) != PROC_NULL
) {
674 error
= proc_pendingsignals(p
, mask
);
682 proc_noremotehang(proc_t p
)
687 retval
= p
->p_flag
& P_NOREMOTEHANG
;
688 return(retval
? 1: 0);
693 proc_exiting(proc_t p
)
698 retval
= p
->p_lflag
& P_LEXIT
;
699 return(retval
? 1: 0);
703 proc_forcequota(proc_t p
)
708 retval
= p
->p_flag
& P_FORCEQUOTA
;
709 return(retval
? 1: 0);
719 retval
= p
->p_flag
& P_TBE
;
720 return(retval
? 1: 0);
727 kauth_cred_t my_cred
;
730 my_cred
= kauth_cred_proc_ref(p
);
731 error
= suser(my_cred
, &p
->p_acflag
);
732 kauth_cred_unref(&my_cred
);
737 * Obtain the first thread in a process
739 * XXX This is a bad thing to do; it exists predominantly to support the
740 * XXX use of proc_t's in places that should really be using
741 * XXX thread_t's instead. This maintains historical behaviour, but really
742 * XXX needs an audit of the context (proxy vs. not) to clean up.
745 proc_thread(proc_t proc
)
747 uthread_t uth
= TAILQ_FIRST(&proc
->p_uthlist
);
750 return(uth
->uu_context
.vc_thread
);
764 thread_t th
= current_thread();
766 return((struct uthread
*)get_bsdthread_info(th
));
771 proc_is64bit(proc_t p
)
773 return(IS_64BIT_PROCESS(p
));
777 proc_pidversion(proc_t p
)
779 return(p
->p_idversion
);
783 proc_getcdhash(proc_t p
, unsigned char *cdhash
)
785 return vn_getcdhash(p
->p_textvp
, p
->p_textoff
, cdhash
);
789 bsd_set_dependency_capable(task_t task
)
791 proc_t p
= get_bsdtask_info(task
);
794 OSBitOrAtomic(P_DEPENDENCY_CAPABLE
, &p
->p_flag
);
800 IS_64BIT_PROCESS(proc_t p
)
802 if (p
&& (p
->p_flag
& P_LP64
))
809 * Locate a process by number
812 pfind_locked(pid_t pid
)
822 for (p
= PIDHASH(pid
)->lh_first
; p
!= 0; p
= p
->p_hash
.le_next
) {
823 if (p
->p_pid
== pid
) {
825 for (q
= p
->p_hash
.le_next
; q
!= 0; q
= q
->p_hash
.le_next
) {
826 if ((p
!=q
) && (q
->p_pid
== pid
))
827 panic("two procs with same pid %p:%p:%d:%d\n", p
, q
, p
->p_pid
, q
->p_pid
);
837 * Locate a zombie by PID
839 __private_extern__ proc_t
847 for (p
= zombproc
.lh_first
; p
!= 0; p
= p
->p_list
.le_next
)
857 * Locate a process group by number
866 pgrp
= pgfind_internal(pgid
);
867 if ((pgrp
== NULL
) || ((pgrp
->pg_listflags
& PGRP_FLAG_TERMINATE
) != 0))
878 pgfind_internal(pid_t pgid
)
882 for (pgrp
= PGRPHASH(pgid
)->lh_first
; pgrp
!= 0; pgrp
= pgrp
->pg_hash
.le_next
)
883 if (pgrp
->pg_id
== pgid
)
889 pg_rele(struct pgrp
* pgrp
)
891 if(pgrp
== PGRP_NULL
)
893 pg_rele_dropref(pgrp
);
897 pg_rele_dropref(struct pgrp
* pgrp
)
900 if ((pgrp
->pg_refcount
== 1) && ((pgrp
->pg_listflags
& PGRP_FLAG_TERMINATE
) == PGRP_FLAG_TERMINATE
)) {
902 pgdelete_dropref(pgrp
);
911 session_find_internal(pid_t sessid
)
913 struct session
*sess
;
915 for (sess
= SESSHASH(sessid
)->lh_first
; sess
!= 0; sess
= sess
->s_hash
.le_next
)
916 if (sess
->s_sid
== sessid
)
923 * Make a new process ready to become a useful member of society by making it
924 * visible in all the right places and initialize its own lists to empty.
926 * Parameters: parent The parent of the process to insert
927 * child The child process to insert
931 * Notes: Insert a child process into the parents process group, assign
932 * the child the parent process pointer and PPID of the parent,
933 * place it on the parents p_children list as a sibling,
934 * initialize its own child list, place it in the allproc list,
935 * insert it in the proper hash bucket, and initialize its
939 pinsertchild(proc_t parent
, proc_t child
)
943 LIST_INIT(&child
->p_children
);
944 TAILQ_INIT(&child
->p_evlist
);
945 child
->p_pptr
= parent
;
946 child
->p_ppid
= parent
->p_pid
;
948 pg
= proc_pgrp(parent
);
949 pgrp_add(pg
, parent
, child
);
953 parent
->p_childrencnt
++;
954 LIST_INSERT_HEAD(&parent
->p_children
, child
, p_sibling
);
956 LIST_INSERT_HEAD(&allproc
, child
, p_list
);
957 /* mark the completion of proc creation */
958 child
->p_listflag
&= ~P_LIST_INCREATE
;
965 * Move p to a new or existing process group (and session)
968 * ESRCH No such process
971 enterpgrp(proc_t p
, pid_t pgid
, int mksess
)
975 struct session
* procsp
;
978 mypgrp
= proc_pgrp(p
);
979 procsp
= proc_session(p
);
982 if (pgrp
!= NULL
&& mksess
) /* firewalls */
983 panic("enterpgrp: setsid into non-empty pgrp");
984 if (SESS_LEADER(p
, procsp
))
985 panic("enterpgrp: session leader attempted setpgrp");
987 if (pgrp
== PGRP_NULL
) {
988 pid_t savepid
= p
->p_pid
;
989 proc_t np
= PROC_NULL
;
994 if (p
->p_pid
!= pgid
)
995 panic("enterpgrp: new pgrp and pid != pgid");
997 MALLOC_ZONE(pgrp
, struct pgrp
*, sizeof(struct pgrp
), M_PGRP
,
1000 panic("enterpgrp: M_PGRP zone depleted");
1001 if ((np
= proc_find(savepid
)) == NULL
|| np
!= p
) {
1002 if (np
!= PROC_NULL
)
1004 if (mypgrp
!= PGRP_NULL
)
1006 if (procsp
!= SESSION_NULL
)
1007 session_rele(procsp
);
1008 FREE_ZONE(pgrp
, sizeof(struct pgrp
), M_PGRP
);
1013 struct session
*sess
;
1018 MALLOC_ZONE(sess
, struct session
*,
1019 sizeof(struct session
), M_SESSION
, M_WAITOK
);
1021 panic("enterpgrp: M_SESSION zone depleted");
1023 sess
->s_sid
= p
->p_pid
;
1025 sess
->s_ttyvp
= NULL
;
1026 sess
->s_ttyp
= TTY_NULL
;
1028 sess
->s_listflags
= 0;
1029 sess
->s_ttypgrpid
= NO_PID
;
1030 #ifdef CONFIG_EMBEDDED
1031 lck_mtx_init(&sess
->s_mlock
, proc_lck_grp
, proc_lck_attr
);
1033 lck_mtx_init(&sess
->s_mlock
, proc_mlock_grp
, proc_lck_attr
);
1035 bcopy(procsp
->s_login
, sess
->s_login
,
1036 sizeof(sess
->s_login
));
1037 OSBitAndAtomic(~((uint32_t)P_CONTROLT
), &p
->p_flag
);
1039 LIST_INSERT_HEAD(SESSHASH(sess
->s_sid
), sess
, s_hash
);
1041 pgrp
->pg_session
= sess
;
1043 if (p
!= current_proc())
1044 panic("enterpgrp: mksession and p != curproc");
1048 pgrp
->pg_session
= procsp
;
1050 if ((pgrp
->pg_session
->s_listflags
& (S_LIST_TERM
| S_LIST_DEAD
)) != 0)
1051 panic("enterpgrp: providing ref to terminating session ");
1052 pgrp
->pg_session
->s_count
++;
1056 #ifdef CONFIG_EMBEDDED
1057 lck_mtx_init(&pgrp
->pg_mlock
, proc_lck_grp
, proc_lck_attr
);
1059 lck_mtx_init(&pgrp
->pg_mlock
, proc_mlock_grp
, proc_lck_attr
);
1061 LIST_INIT(&pgrp
->pg_members
);
1062 pgrp
->pg_membercnt
= 0;
1065 pgrp
->pg_refcount
= 1;
1066 pgrp
->pg_listflags
= 0;
1067 LIST_INSERT_HEAD(PGRPHASH(pgid
), pgrp
, pg_hash
);
1069 } else if (pgrp
== mypgrp
) {
1073 if (procsp
!= SESSION_NULL
)
1074 session_rele(procsp
);
1078 if (procsp
!= SESSION_NULL
)
1079 session_rele(procsp
);
1081 * Adjust eligibility of affected pgrps to participate in job control.
1082 * Increment eligibility counts before decrementing, otherwise we
1083 * could reach 0 spuriously during the first call.
1085 fixjobc(p
, pgrp
, 1);
1086 fixjobc(p
, mypgrp
, 0);
1088 if(mypgrp
!= PGRP_NULL
)
1090 pgrp_replace(p
, pgrp
);
1097 * remove process from process group
1108 * delete a process group
1111 pgdelete_dropref(struct pgrp
*pgrp
)
1115 struct session
*sessp
;
1119 if (pgrp
->pg_membercnt
!= 0) {
1125 pgrp
->pg_refcount
--;
1126 if ((emptypgrp
== 0) || (pgrp
->pg_membercnt
!= 0)) {
1131 pgrp
->pg_listflags
|= PGRP_FLAG_TERMINATE
;
1133 if (pgrp
->pg_refcount
> 0) {
1138 pgrp
->pg_listflags
|= PGRP_FLAG_DEAD
;
1139 LIST_REMOVE(pgrp
, pg_hash
);
1143 ttyp
= SESSION_TP(pgrp
->pg_session
);
1144 if (ttyp
!= TTY_NULL
) {
1145 if (ttyp
->t_pgrp
== pgrp
) {
1147 /* Re-check after acquiring the lock */
1148 if (ttyp
->t_pgrp
== pgrp
) {
1149 ttyp
->t_pgrp
= NULL
;
1150 pgrp
->pg_session
->s_ttypgrpid
= NO_PID
;
1158 sessp
= pgrp
->pg_session
;
1159 if ((sessp
->s_listflags
& (S_LIST_TERM
| S_LIST_DEAD
)) != 0)
1160 panic("pg_deleteref: manipulating refs of already terminating session");
1161 if (--sessp
->s_count
== 0) {
1162 if ((sessp
->s_listflags
& (S_LIST_TERM
| S_LIST_DEAD
)) != 0)
1163 panic("pg_deleteref: terminating already terminated session");
1164 sessp
->s_listflags
|= S_LIST_TERM
;
1165 ttyp
= SESSION_TP(sessp
);
1166 LIST_REMOVE(sessp
, s_hash
);
1168 if (ttyp
!= TTY_NULL
) {
1170 if (ttyp
->t_session
== sessp
)
1171 ttyp
->t_session
= NULL
;
1175 sessp
->s_listflags
|= S_LIST_DEAD
;
1176 if (sessp
->s_count
!= 0)
1177 panic("pg_deleteref: freeing session in use");
1179 #ifdef CONFIG_EMBEDDED
1180 lck_mtx_destroy(&sessp
->s_mlock
, proc_lck_grp
);
1182 lck_mtx_destroy(&sessp
->s_mlock
, proc_mlock_grp
);
1184 FREE_ZONE(sessp
, sizeof(struct session
), M_SESSION
);
1187 #ifdef CONFIG_EMBEDDED
1188 lck_mtx_destroy(&pgrp
->pg_mlock
, proc_lck_grp
);
1190 lck_mtx_destroy(&pgrp
->pg_mlock
, proc_mlock_grp
);
1192 FREE_ZONE(pgrp
, sizeof(*pgrp
), M_PGRP
);
1197 * Adjust pgrp jobc counters when specified process changes process group.
1198 * We count the number of processes in each process group that "qualify"
1199 * the group for terminal job control (those with a parent in a different
1200 * process group of the same session). If that count reaches zero, the
1201 * process group becomes orphaned. Check both the specified process'
1202 * process group and that of its children.
1203 * entering == 0 => p is leaving specified group.
1204 * entering == 1 => p is entering specified group.
1207 fixjob_callback(proc_t p
, void * arg
)
1209 struct fixjob_iterargs
*fp
;
1210 struct pgrp
* pg
, *hispg
;
1211 struct session
* mysession
, *hissess
;
1214 fp
= (struct fixjob_iterargs
*)arg
;
1216 mysession
= fp
->mysession
;
1217 entering
= fp
->entering
;
1219 hispg
= proc_pgrp(p
);
1220 hissess
= proc_session(p
);
1222 if ((hispg
!= pg
) &&
1223 (hissess
== mysession
)) {
1228 } else if (--hispg
->pg_jobc
== 0) {
1234 if (hissess
!= SESSION_NULL
)
1235 session_rele(hissess
);
1236 if (hispg
!= PGRP_NULL
)
1239 return(PROC_RETURNED
);
1243 fixjobc(proc_t p
, struct pgrp
*pgrp
, int entering
)
1245 struct pgrp
*hispgrp
= PGRP_NULL
;
1246 struct session
*hissess
= SESSION_NULL
;
1247 struct session
*mysession
= pgrp
->pg_session
;
1249 struct fixjob_iterargs fjarg
;
1251 parent
= proc_parent(p
);
1252 if (parent
!= PROC_NULL
) {
1253 hispgrp
= proc_pgrp(parent
);
1254 hissess
= proc_session(parent
);
1260 * Check p's parent to see whether p qualifies its own process
1261 * group; if so, adjust count for p's process group.
1263 if ((hispgrp
!= pgrp
) &&
1264 (hissess
== mysession
)) {
1269 }else if (--pgrp
->pg_jobc
== 0) {
1276 if (hissess
!= SESSION_NULL
)
1277 session_rele(hissess
);
1278 if (hispgrp
!= PGRP_NULL
)
1282 * Check this process' children to see whether they qualify
1283 * their process groups; if so, adjust counts for children's
1287 fjarg
.mysession
= mysession
;
1288 fjarg
.entering
= entering
;
1289 proc_childrenwalk(p
, fixjob_callback
, &fjarg
);
1293 * A process group has become orphaned;
1294 * if there are any stopped processes in the group,
1295 * hang-up all process in that group.
1298 orphanpg(struct pgrp
* pgrp
)
1302 int count
, pidcount
, i
, alloc_count
;
1304 if (pgrp
== PGRP_NULL
)
1308 for (p
= pgrp
->pg_members
.lh_first
; p
!= 0; p
= p
->p_pglist
.le_next
) {
1309 if (p
->p_stat
== SSTOP
) {
1310 for (p
= pgrp
->pg_members
.lh_first
; p
!= 0;
1311 p
= p
->p_pglist
.le_next
)
1313 break; /* ??? stops after finding one.. */
1319 if (count
> hard_maxproc
)
1320 count
= hard_maxproc
;
1321 alloc_count
= count
* sizeof(pid_t
);
1322 pid_list
= (pid_t
*)kalloc(alloc_count
);
1323 bzero(pid_list
, alloc_count
);
1327 for (p
= pgrp
->pg_members
.lh_first
; p
!= 0;
1328 p
= p
->p_pglist
.le_next
) {
1329 if (p
->p_stat
== SSTOP
) {
1330 for (p
= pgrp
->pg_members
.lh_first
; p
!= 0;
1331 p
= p
->p_pglist
.le_next
) {
1332 pid_list
[pidcount
] = p
->p_pid
;
1334 if (pidcount
>= count
)
1337 break; /* ??? stops after finding one.. */
1346 for (i
= 0; i
< pidcount
; i
++) {
1347 /* No handling or proc0 */
1348 if (pid_list
[i
] == 0)
1350 p
= proc_find(pid_list
[i
]);
1352 proc_transwait(p
, 0);
1355 psignal(p
, SIGCONT
);
1360 kfree(pid_list
, alloc_count
);
1366 /* XXX should be __private_extern__ */
1368 proc_is_classic(proc_t p
)
1370 return (p
->p_flag
& P_TRANSLATED
) ? 1 : 0;
1373 /* XXX Why does this function exist? Need to kill it off... */
1375 current_proc_EXTERNAL(void)
1377 return (current_proc());
1381 * proc_core_name(name, uid, pid)
1382 * Expand the name described in corefilename, using name, uid, and pid.
1383 * corefilename is a printf-like string, with three format specifiers:
1384 * %N name of process ("name")
1385 * %P process id (pid)
1387 * For example, "%N.core" is the default; they can be disabled completely
1388 * by using "/dev/null", or all core files can be stored in "/cores/%U/%N-%P".
1389 * This is controlled by the sysctl variable kern.corefile (see above).
1391 __private_extern__
int
1392 proc_core_name(const char *name
, uid_t uid
, pid_t pid
, char *cf_name
,
1395 const char *format
, *appendstr
;
1396 char id_buf
[11]; /* Buffer for pid/uid -- max 4B */
1399 if (cf_name
== NULL
)
1402 format
= corefilename
;
1403 for (i
= 0, n
= 0; n
< cf_name_len
&& format
[i
]; i
++) {
1404 switch (format
[i
]) {
1405 case '%': /* Format character */
1407 switch (format
[i
]) {
1411 case 'N': /* process name */
1414 case 'P': /* process id */
1415 snprintf(id_buf
, sizeof(id_buf
), "%u", pid
);
1418 case 'U': /* user id */
1419 snprintf(id_buf
, sizeof(id_buf
), "%u", uid
);
1425 "Unknown format character %c in `%s'\n",
1428 l
= strlen(appendstr
);
1429 if ((n
+ l
) >= cf_name_len
)
1431 bcopy(appendstr
, cf_name
+ n
, l
);
1435 cf_name
[n
++] = format
[i
];
1438 if (format
[i
] != '\0')
1442 log(LOG_ERR
, "pid %ld (%s), uid (%u): corename is too long\n",
1443 (long)pid
, name
, (uint32_t)uid
);
1452 LIST_INIT(&alllctx
);
1455 /* allocate lctx lock group attribute and group */
1456 lctx_lck_grp_attr
= lck_grp_attr_alloc_init();
1457 lck_grp_attr_setstat(lctx_lck_grp_attr
);
1459 lctx_lck_grp
= lck_grp_alloc_init("lctx", lctx_lck_grp_attr
);
1460 /* Allocate lctx lock attribute */
1461 lctx_lck_attr
= lck_attr_alloc_init();
1463 lck_mtx_init(&alllctx_lock
, lctx_lck_grp
, lctx_lck_attr
);
1467 * Locate login context by number.
1475 LIST_FOREACH(l
, &alllctx
, lc_list
) {
1476 if (l
->lc_id
== lcid
) {
1488 if (lastlcid > maxlcid) \
1498 /* Not very efficient but this isn't a common operation. */
1499 while ((l
= lcfind(lastlcid
)) != NULL
) {
1506 MALLOC(l
, struct lctx
*, sizeof(struct lctx
), M_LCTX
, M_WAITOK
|M_ZERO
);
1508 LIST_INIT(&l
->lc_members
);
1509 lck_mtx_init(&l
->lc_mtx
, lctx_lck_grp
, lctx_lck_attr
);
1511 l
->lc_label
= mac_lctx_label_alloc();
1514 LIST_INSERT_HEAD(&alllctx
, l
, lc_list
);
1522 * Call with proc protected (either by being invisible
1523 * or by having the all-login-context lock held) and
1526 * Will unlock lctx on return.
1529 enterlctx (proc_t p
, struct lctx
*l
, __unused
int create
)
1535 LIST_INSERT_HEAD(&l
->lc_members
, p
, p_lclist
);
1540 mac_lctx_notify_create(p
, l
);
1542 mac_lctx_notify_join(p
, l
);
1550 * Remove process from login context (if any). Called with p protected by
1554 leavelctx (proc_t p
)
1558 if (p
->p_lctx
== NULL
) {
1562 LCTX_LOCK(p
->p_lctx
);
1565 LIST_REMOVE(p
, p_lclist
);
1568 mac_lctx_notify_leave(p
, l
);
1570 if (LIST_EMPTY(&l
->lc_members
)) {
1571 LIST_REMOVE(l
, lc_list
);
1574 lck_mtx_destroy(&l
->lc_mtx
, lctx_lck_grp
);
1576 mac_lctx_label_free(l
->lc_label
);
1587 sysctl_kern_lctx SYSCTL_HANDLER_ARGS
1589 int *name
= (int*) arg1
;
1590 u_int namelen
= arg2
;
1591 struct kinfo_lctx kil
;
1597 switch (oidp
->oid_number
) {
1600 /* Request for size. */
1602 error
= SYSCTL_OUT(req
, 0,
1603 sizeof(struct kinfo_lctx
) * (alllctx_cnt
+ 1));
1608 case KERN_LCTX_LCID
:
1610 if (req
->oldlen
< sizeof(struct kinfo_lctx
))
1615 /* No login context */
1616 l
= lcfind((pid_t
)name
[0]);
1622 return (SYSCTL_OUT(req
, (caddr_t
)&kil
, sizeof(kil
)));
1628 /* Provided buffer is too small. */
1629 if (req
->oldlen
< (sizeof(struct kinfo_lctx
) * alllctx_cnt
)) {
1634 LIST_FOREACH(l
, &alllctx
, lc_list
) {
1639 error
= SYSCTL_OUT(req
, (caddr_t
)&kil
, sizeof(kil
));
1649 SYSCTL_NODE(_kern
, KERN_LCTX
, lctx
, CTLFLAG_RW
|CTLFLAG_LOCKED
, 0, "Login Context");
1651 SYSCTL_PROC(_kern_lctx
, KERN_LCTX_ALL
, all
, CTLFLAG_RD
|CTLTYPE_STRUCT
,
1652 0, 0, sysctl_kern_lctx
, "S,lctx",
1653 "Return entire login context table");
1654 SYSCTL_NODE(_kern_lctx
, KERN_LCTX_LCID
, lcid
, CTLFLAG_RD
,
1655 sysctl_kern_lctx
, "Login Context Table");
1656 SYSCTL_INT(_kern_lctx
, OID_AUTO
, last
, CTLFLAG_RD
, &lastlcid
, 0, "");
1657 SYSCTL_INT(_kern_lctx
, OID_AUTO
, count
, CTLFLAG_RD
, &alllctx_cnt
, 0, "");
1658 SYSCTL_INT(_kern_lctx
, OID_AUTO
, max
, CTLFLAG_RW
, &maxlcid
, 0, "");
1662 /* Code Signing related routines */
1665 csops(__unused proc_t p
, struct csops_args
*uap
, __unused
int32_t *retval
)
1668 pid_t pid
= uap
->pid
;
1669 user_addr_t uaddr
= uap
->useraddr
;
1670 size_t usize
= (size_t)CAST_DOWN(size_t, uap
->usersize
);
1678 unsigned char cdhash
[SHA1_RESULTLEN
];
1680 forself
= error
= 0;
1683 pid
= proc_selfpid();
1684 if (pid
== proc_selfpid())
1688 /* Pre flight checks for CS_OPS_PIDPATH */
1689 if (ops
== CS_OPS_PIDPATH
) {
1690 /* usize is unsigned.. */
1691 if (usize
> 4 * PATH_MAX
)
1693 if (kauth_cred_issuser(kauth_cred_get()) != TRUE
)
1695 } else if ((forself
== 0) && ((ops
!= CS_OPS_STATUS
) && (ops
!= CS_OPS_CDHASH
) && (ops
!= CS_OPS_PIDOFFSET
) && (kauth_cred_issuser(kauth_cred_get()) != TRUE
))) {
1699 pt
= proc_find(pid
);
1700 if (pt
== PROC_NULL
)
1708 retflags
= pt
->p_csflags
;
1709 if (uaddr
!= USER_ADDR_NULL
)
1710 error
= copyout(&retflags
, uaddr
, sizeof(uint32_t));
1713 case CS_OPS_MARKINVALID
:
1715 if ((pt
->p_csflags
& CS_VALID
) == CS_VALID
) { /* is currently valid */
1716 pt
->p_csflags
&= ~CS_VALID
; /* set invalid */
1717 if ((pt
->p_csflags
& CS_KILL
) == CS_KILL
) {
1719 psignal(pt
, SIGKILL
);
1727 case CS_OPS_MARKHARD
:
1729 pt
->p_csflags
|= CS_HARD
;
1730 if ((pt
->p_csflags
& CS_VALID
) == 0) {
1731 /* @@@ allow? reject? kill? @@@ */
1739 case CS_OPS_MARKKILL
:
1741 pt
->p_csflags
|= CS_KILL
;
1742 if ((pt
->p_csflags
& CS_VALID
) == 0) {
1744 psignal(pt
, SIGKILL
);
1749 case CS_OPS_PIDPATH
:
1751 vid
= vnode_vid(tvp
);
1753 if (tvp
== NULLVP
) {
1758 buf
= (char *)kalloc(usize
);
1765 error
= vnode_getwithvid(tvp
, vid
);
1769 error
= vn_getpath(tvp
, buf
, &len
);
1772 error
= copyout(buf
, uaddr
, usize
);
1781 case CS_OPS_PIDOFFSET
:
1782 toff
= pt
->p_textoff
;
1784 error
= copyout(&toff
, uaddr
, sizeof(toff
));
1789 /* pt already holds a reference on its p_textvp */
1791 toff
= pt
->p_textoff
;
1793 if (tvp
== NULLVP
|| usize
!= SHA1_RESULTLEN
) {
1798 error
= vn_getcdhash(tvp
, toff
, cdhash
);
1802 error
= copyout(cdhash
, uaddr
, sizeof (cdhash
));
1818 proc_iterate(flags
, callout
, arg
, filterfn
, filterarg
)
1820 int (*callout
)(proc_t
, void *);
1822 int (*filterfn
)(proc_t
, void *);
1827 int count
, pidcount
, alloc_count
, i
, retval
;
1830 if (count
> hard_maxproc
)
1831 count
= hard_maxproc
;
1832 alloc_count
= count
* sizeof(pid_t
);
1833 pid_list
= (pid_t
*)kalloc(alloc_count
);
1834 bzero(pid_list
, alloc_count
);
1841 if (flags
& PROC_ALLPROCLIST
) {
1842 for (p
= allproc
.lh_first
; (p
!= 0); p
= p
->p_list
.le_next
) {
1843 if (p
->p_stat
== SIDL
)
1845 if ( (filterfn
== 0 ) || (filterfn(p
, filterarg
) != 0)) {
1846 pid_list
[pidcount
] = p
->p_pid
;
1848 if (pidcount
>= count
)
1853 if ((pidcount
< count
) && (flags
& PROC_ZOMBPROCLIST
)) {
1854 for (p
= zombproc
.lh_first
; p
!= 0; p
= p
->p_list
.le_next
) {
1855 if ( (filterfn
== 0 ) || (filterfn(p
, filterarg
) != 0)) {
1856 pid_list
[pidcount
] = p
->p_pid
;
1858 if (pidcount
>= count
)
1868 for (i
= 0; i
< pidcount
; i
++) {
1869 p
= proc_find(pid_list
[i
]);
1871 if ((flags
& PROC_NOWAITTRANS
) == 0)
1872 proc_transwait(p
, 0);
1873 retval
= callout(p
, arg
);
1877 case PROC_RETURNED_DONE
:
1879 if (retval
== PROC_RETURNED_DONE
) {
1884 case PROC_CLAIMED_DONE
:
1890 } else if (flags
& PROC_ZOMBPROCLIST
) {
1891 p
= proc_find_zombref(pid_list
[i
]);
1892 if (p
!= PROC_NULL
) {
1893 retval
= callout(p
, arg
);
1897 case PROC_RETURNED_DONE
:
1898 proc_drop_zombref(p
);
1899 if (retval
== PROC_RETURNED_DONE
) {
1904 case PROC_CLAIMED_DONE
:
1915 kfree(pid_list
, alloc_count
);
1922 /* This is for iteration in case of trivial non blocking callouts */
1924 proc_scanall(flags
, callout
, arg
)
1926 int (*callout
)(proc_t
, void *);
1936 if (flags
& PROC_ALLPROCLIST
) {
1937 for (p
= allproc
.lh_first
; (p
!= 0); p
= p
->p_list
.le_next
) {
1938 retval
= callout(p
, arg
);
1939 if (retval
== PROC_RETURNED_DONE
)
1943 if (flags
& PROC_ZOMBPROCLIST
) {
1944 for (p
= zombproc
.lh_first
; p
!= 0; p
= p
->p_list
.le_next
) {
1945 retval
= callout(p
, arg
);
1946 if (retval
== PROC_RETURNED_DONE
)
1960 proc_rebootscan(callout
, arg
, filterfn
, filterarg
)
1961 int (*callout
)(proc_t
, void *);
1963 int (*filterfn
)(proc_t
, void *);
1967 int lockheld
= 0, retval
;
1969 proc_shutdown_exitcount
= 0;
1977 for (p
= allproc
.lh_first
; (p
!= 0); p
= p
->p_list
.le_next
) {
1978 if ( (filterfn
== 0 ) || (filterfn(p
, filterarg
) != 0)) {
1979 p
= proc_refinternal_locked(p
);
1985 proc_transwait(p
, 0);
1986 retval
= callout(p
, arg
);
1990 case PROC_RETURNED_DONE
:
1991 case PROC_CLAIMED_DONE
:
1995 goto ps_allprocscan
;
1997 } /* allproc walk thru */
1999 if (lockheld
== 1) {
2011 proc_childrenwalk(parent
, callout
, arg
)
2012 struct proc
* parent
;
2013 int (*callout
)(proc_t
, void *);
2016 register struct proc
*p
;
2018 int count
, pidcount
, alloc_count
, i
, retval
;
2021 if (count
> hard_maxproc
)
2022 count
= hard_maxproc
;
2023 alloc_count
= count
* sizeof(pid_t
);
2024 pid_list
= (pid_t
*)kalloc(alloc_count
);
2025 bzero(pid_list
, alloc_count
);
2032 for (p
= parent
->p_children
.lh_first
; (p
!= 0); p
= p
->p_sibling
.le_next
) {
2033 if (p
->p_stat
== SIDL
)
2035 pid_list
[pidcount
] = p
->p_pid
;
2037 if (pidcount
>= count
)
2043 for (i
= 0; i
< pidcount
; i
++) {
2044 p
= proc_find(pid_list
[i
]);
2046 proc_transwait(p
, 0);
2047 retval
= callout(p
, arg
);
2051 case PROC_RETURNED_DONE
:
2053 if (retval
== PROC_RETURNED_DONE
) {
2058 case PROC_CLAIMED_DONE
:
2068 kfree(pid_list
, alloc_count
);
2075 /* PGRP_BLOCKITERATE is not implemented yet */
2077 pgrp_iterate(pgrp
, flags
, callout
, arg
, filterfn
, filterarg
)
2080 int (*callout
)(proc_t
, void *);
2082 int (*filterfn
)(proc_t
, void *);
2087 int count
, pidcount
, i
, alloc_count
;
2090 int dropref
= flags
& PGRP_DROPREF
;
2092 int serialize
= flags
& PGRP_BLOCKITERATE
;
2099 count
= pgrp
->pg_membercnt
+ 10;
2100 if (count
> hard_maxproc
)
2101 count
= hard_maxproc
;
2102 alloc_count
= count
* sizeof(pid_t
);
2103 pid_list
= (pid_t
*)kalloc(alloc_count
);
2104 bzero(pid_list
, alloc_count
);
2107 if (serialize
!= 0) {
2108 while ((pgrp
->pg_listflags
& PGRP_FLAG_ITERABEGIN
) == PGRP_FLAG_ITERABEGIN
) {
2109 pgrp
->pg_listflags
|= PGRP_FLAG_ITERWAIT
;
2110 msleep(&pgrp
->pg_listflags
, &pgrp
->pg_mlock
, 0, "pgrp_iterate", 0);
2112 pgrp
->pg_listflags
|= PGRP_FLAG_ITERABEGIN
;
2118 for (p
= pgrp
->pg_members
.lh_first
; p
!= 0;
2119 p
= p
->p_pglist
.le_next
) {
2120 if ( (filterfn
== 0 ) || (filterfn(p
, filterarg
) != 0)) {
2121 pid_list
[pidcount
] = p
->p_pid
;
2123 if (pidcount
>= count
)
2130 if ((serialize
== 0) && (dropref
!= 0))
2134 for (i
= 0; i
< pidcount
; i
++) {
2135 /* No handling or proc0 */
2136 if (pid_list
[i
] == 0)
2138 p
= proc_find(pid_list
[i
]);
2140 if (p
->p_pgrpid
!= pgid
) {
2144 proc_transwait(p
, 0);
2145 retval
= callout(p
, arg
);
2149 case PROC_RETURNED_DONE
:
2151 if (retval
== PROC_RETURNED_DONE
) {
2156 case PROC_CLAIMED_DONE
:
2165 if (serialize
!= 0) {
2167 pgrp
->pg_listflags
&= ~PGRP_FLAG_ITERABEGIN
;
2168 if ((pgrp
->pg_listflags
& PGRP_FLAG_ITERWAIT
) == PGRP_FLAG_ITERWAIT
) {
2169 pgrp
->pg_listflags
&= ~PGRP_FLAG_ITERWAIT
;
2170 wakeup(&pgrp
->pg_listflags
);
2176 kfree(pid_list
, alloc_count
);
2181 pgrp_add(struct pgrp
* pgrp
, struct proc
* parent
, struct proc
* child
)
2184 child
->p_pgrp
= pgrp
;
2185 child
->p_pgrpid
= pgrp
->pg_id
;
2186 child
->p_listflag
|= P_LIST_INPGRP
;
2188 * When pgrp is being freed , a process can still
2189 * request addition using setpgid from bash when
2190 * login is terminated (login cycler) return ESRCH
2191 * Safe to hold lock due to refcount on pgrp
2193 if ((pgrp
->pg_listflags
& (PGRP_FLAG_TERMINATE
| PGRP_FLAG_DEAD
)) == PGRP_FLAG_TERMINATE
) {
2194 pgrp
->pg_listflags
&= ~PGRP_FLAG_TERMINATE
;
2197 if ((pgrp
->pg_listflags
& PGRP_FLAG_DEAD
) == PGRP_FLAG_DEAD
)
2198 panic("pgrp_add : pgrp is dead adding process");
2202 pgrp
->pg_membercnt
++;
2203 if ( parent
!= PROC_NULL
) {
2204 LIST_INSERT_AFTER(parent
, child
, p_pglist
);
2206 LIST_INSERT_HEAD(&pgrp
->pg_members
, child
, p_pglist
);
2211 if (((pgrp
->pg_listflags
& (PGRP_FLAG_TERMINATE
| PGRP_FLAG_DEAD
)) == PGRP_FLAG_TERMINATE
) && (pgrp
->pg_membercnt
!= 0)) {
2212 pgrp
->pg_listflags
&= ~PGRP_FLAG_TERMINATE
;
2218 pgrp_remove(struct proc
* p
)
2225 #if __PROC_INTERNAL_DEBUG
2226 if ((p
->p_listflag
& P_LIST_INPGRP
) == 0)
2227 panic("removing from pglist but no named ref\n");
2229 p
->p_pgrpid
= PGRPID_DEAD
;
2230 p
->p_listflag
&= ~P_LIST_INPGRP
;
2234 if (pg
== PGRP_NULL
)
2235 panic("pgrp_remove: pg is NULL");
2239 if (pg
->pg_membercnt
< 0)
2240 panic("pgprp: -ve membercnt pgprp:%p p:%p\n",pg
, p
);
2242 LIST_REMOVE(p
, p_pglist
);
2243 if (pg
->pg_members
.lh_first
== 0) {
2245 pgdelete_dropref(pg
);
2253 /* cannot use proc_pgrp as it maybe stalled */
2255 pgrp_replace(struct proc
* p
, struct pgrp
* newpg
)
2257 struct pgrp
* oldpg
;
2263 while ((p
->p_listflag
& P_LIST_PGRPTRANS
) == P_LIST_PGRPTRANS
) {
2264 p
->p_listflag
|= P_LIST_PGRPTRWAIT
;
2265 (void)msleep(&p
->p_pgrpid
, proc_list_mlock
, 0, "proc_pgrp", 0);
2268 p
->p_listflag
|= P_LIST_PGRPTRANS
;
2271 if (oldpg
== PGRP_NULL
)
2272 panic("pgrp_replace: oldpg NULL");
2273 oldpg
->pg_refcount
++;
2274 #if __PROC_INTERNAL_DEBUG
2275 if ((p
->p_listflag
& P_LIST_INPGRP
) == 0)
2276 panic("removing from pglist but no named ref\n");
2278 p
->p_pgrpid
= PGRPID_DEAD
;
2279 p
->p_listflag
&= ~P_LIST_INPGRP
;
2285 oldpg
->pg_membercnt
--;
2286 if (oldpg
->pg_membercnt
< 0)
2287 panic("pgprp: -ve membercnt pgprp:%p p:%p\n",oldpg
, p
);
2288 LIST_REMOVE(p
, p_pglist
);
2289 if (oldpg
->pg_members
.lh_first
== 0) {
2291 pgdelete_dropref(oldpg
);
2299 p
->p_pgrpid
= newpg
->pg_id
;
2300 p
->p_listflag
|= P_LIST_INPGRP
;
2302 * When pgrp is being freed , a process can still
2303 * request addition using setpgid from bash when
2304 * login is terminated (login cycler) return ESRCH
2305 * Safe to hold lock due to refcount on pgrp
2307 if ((newpg
->pg_listflags
& (PGRP_FLAG_TERMINATE
| PGRP_FLAG_DEAD
)) == PGRP_FLAG_TERMINATE
) {
2308 newpg
->pg_listflags
&= ~PGRP_FLAG_TERMINATE
;
2311 if ((newpg
->pg_listflags
& PGRP_FLAG_DEAD
) == PGRP_FLAG_DEAD
)
2312 panic("pgrp_add : pgrp is dead adding process");
2316 newpg
->pg_membercnt
++;
2317 LIST_INSERT_HEAD(&newpg
->pg_members
, p
, p_pglist
);
2321 if (((newpg
->pg_listflags
& (PGRP_FLAG_TERMINATE
| PGRP_FLAG_DEAD
)) == PGRP_FLAG_TERMINATE
) && (newpg
->pg_membercnt
!= 0)) {
2322 newpg
->pg_listflags
&= ~PGRP_FLAG_TERMINATE
;
2325 p
->p_listflag
&= ~P_LIST_PGRPTRANS
;
2326 if ((p
->p_listflag
& P_LIST_PGRPTRWAIT
) == P_LIST_PGRPTRWAIT
) {
2327 p
->p_listflag
&= ~P_LIST_PGRPTRWAIT
;
2328 wakeup(&p
->p_pgrpid
);
2335 pgrp_lock(struct pgrp
* pgrp
)
2337 lck_mtx_lock(&pgrp
->pg_mlock
);
2341 pgrp_unlock(struct pgrp
* pgrp
)
2343 lck_mtx_unlock(&pgrp
->pg_mlock
);
2347 session_lock(struct session
* sess
)
2349 lck_mtx_lock(&sess
->s_mlock
);
2354 session_unlock(struct session
* sess
)
2356 lck_mtx_unlock(&sess
->s_mlock
);
2368 while ((p
->p_listflag
& P_LIST_PGRPTRANS
) == P_LIST_PGRPTRANS
) {
2369 p
->p_listflag
|= P_LIST_PGRPTRWAIT
;
2370 (void)msleep(&p
->p_pgrpid
, proc_list_mlock
, 0, "proc_pgrp", 0);
2375 assert(pgrp
!= NULL
);
2377 if (pgrp
!= PGRP_NULL
) {
2378 pgrp
->pg_refcount
++;
2379 if ((pgrp
->pg_listflags
& (PGRP_FLAG_TERMINATE
| PGRP_FLAG_DEAD
)) != 0)
2380 panic("proc_pgrp: ref being povided for dead pgrp");
2389 tty_pgrp(struct tty
* tp
)
2391 struct pgrp
* pg
= PGRP_NULL
;
2396 if (pg
!= PGRP_NULL
) {
2397 if ((pg
->pg_listflags
& PGRP_FLAG_DEAD
) != 0)
2398 panic("tty_pgrp: ref being povided for dead pgrp");
2407 proc_session(proc_t p
)
2409 struct session
* sess
= SESSION_NULL
;
2412 return(SESSION_NULL
);
2416 /* wait during transitions */
2417 while ((p
->p_listflag
& P_LIST_PGRPTRANS
) == P_LIST_PGRPTRANS
) {
2418 p
->p_listflag
|= P_LIST_PGRPTRWAIT
;
2419 (void)msleep(&p
->p_pgrpid
, proc_list_mlock
, 0, "proc_pgrp", 0);
2422 if ((p
->p_pgrp
!= PGRP_NULL
) && ((sess
= p
->p_pgrp
->pg_session
) != SESSION_NULL
)) {
2423 if ((sess
->s_listflags
& (S_LIST_TERM
| S_LIST_DEAD
)) != 0)
2424 panic("proc_session:returning sesssion ref on terminating session");
2432 session_rele(struct session
*sess
)
2435 if (--sess
->s_count
== 0) {
2436 if ((sess
->s_listflags
& (S_LIST_TERM
| S_LIST_DEAD
)) != 0)
2437 panic("session_rele: terminating already terminated session");
2438 sess
->s_listflags
|= S_LIST_TERM
;
2439 LIST_REMOVE(sess
, s_hash
);
2440 sess
->s_listflags
|= S_LIST_DEAD
;
2441 if (sess
->s_count
!= 0)
2442 panic("session_rele: freeing session in use");
2444 #ifdef CONFIG_EMBEDDED
2445 lck_mtx_destroy(&sess
->s_mlock
, proc_lck_grp
);
2447 lck_mtx_destroy(&sess
->s_mlock
, proc_mlock_grp
);
2449 FREE_ZONE(sess
, sizeof(struct session
), M_SESSION
);
2455 proc_transstart(proc_t p
, int locked
)
2459 while ((p
->p_lflag
& P_LINTRANSIT
) == P_LINTRANSIT
) {
2460 if ((p
->p_lflag
& P_LTRANSCOMMIT
) == P_LTRANSCOMMIT
) {
2465 p
->p_lflag
|= P_LTRANSWAIT
;
2466 msleep(&p
->p_lflag
, &p
->p_mlock
, 0, "proc_signstart", NULL
);
2468 p
->p_lflag
|= P_LINTRANSIT
;
2469 p
->p_transholder
= current_thread();
2476 proc_transcommit(proc_t p
, int locked
)
2481 assert ((p
->p_lflag
& P_LINTRANSIT
) == P_LINTRANSIT
);
2482 assert (p
->p_transholder
== current_thread());
2483 p
->p_lflag
|= P_LTRANSCOMMIT
;
2485 if ((p
->p_lflag
& P_LTRANSWAIT
) == P_LTRANSWAIT
) {
2486 p
->p_lflag
&= ~P_LTRANSWAIT
;
2487 wakeup(&p
->p_lflag
);
2494 proc_transend(proc_t p
, int locked
)
2499 p
->p_lflag
&= ~( P_LINTRANSIT
| P_LTRANSCOMMIT
);
2500 p
->p_transholder
= NULL
;
2502 if ((p
->p_lflag
& P_LTRANSWAIT
) == P_LTRANSWAIT
) {
2503 p
->p_lflag
&= ~P_LTRANSWAIT
;
2504 wakeup(&p
->p_lflag
);
2511 proc_transwait(proc_t p
, int locked
)
2515 while ((p
->p_lflag
& P_LINTRANSIT
) == P_LINTRANSIT
) {
2516 if ((p
->p_lflag
& P_LTRANSCOMMIT
) == P_LTRANSCOMMIT
&& current_proc() == p
) {
2521 p
->p_lflag
|= P_LTRANSWAIT
;
2522 msleep(&p
->p_lflag
, &p
->p_mlock
, 0, "proc_signstart", NULL
);
2530 proc_klist_lock(void)
2532 lck_mtx_lock(proc_klist_mlock
);
2536 proc_klist_unlock(void)
2538 lck_mtx_unlock(proc_klist_mlock
);
2542 proc_knote(struct proc
* p
, long hint
)
2545 KNOTE(&p
->p_klist
, hint
);
2546 proc_klist_unlock();
2550 proc_knote_drain(struct proc
*p
)
2552 struct knote
*kn
= NULL
;
2555 * Clear the proc's klist to avoid references after the proc is reaped.
2558 while ((kn
= SLIST_FIRST(&p
->p_klist
))) {
2559 kn
->kn_ptr
.p_proc
= PROC_NULL
;
2560 KNOTE_DETACH(&p
->p_klist
, kn
);
2562 proc_klist_unlock();
2565 unsigned long cs_procs_killed
= 0;
2566 unsigned long cs_procs_invalidated
= 0;
2567 int cs_force_kill
= 0;
2568 int cs_force_hard
= 0;
2570 SYSCTL_INT(_vm
, OID_AUTO
, cs_force_kill
, CTLFLAG_RW
, &cs_force_kill
, 0, "");
2571 SYSCTL_INT(_vm
, OID_AUTO
, cs_force_hard
, CTLFLAG_RW
, &cs_force_hard
, 0, "");
2572 SYSCTL_INT(_vm
, OID_AUTO
, cs_debug
, CTLFLAG_RW
, &cs_debug
, 0, "");
2575 cs_allow_invalid(struct proc
*p
)
2578 lck_mtx_assert(&p
->p_mlock
, LCK_MTX_ASSERT_NOTOWNED
);
2580 #if CONFIG_MACF && CONFIG_ENFORCE_SIGNED_CODE
2581 /* There needs to be a MAC policy to implement this hook, or else the
2582 * kill bits will be cleared here every time. If we have
2583 * CONFIG_ENFORCE_SIGNED_CODE, we can assume there is a policy
2584 * implementing the hook.
2586 if( 0 != mac_proc_check_run_cs_invalid(p
)) {
2587 if(cs_debug
) printf("CODE SIGNING: cs_allow_invalid() "
2588 "not allowed: pid %d\n",
2592 if(cs_debug
) printf("CODE SIGNING: cs_allow_invalid() "
2593 "allowed: pid %d\n",
2596 p
->p_csflags
&= ~(CS_KILL
| CS_HARD
| CS_VALID
);
2598 vm_map_switch_protect(get_task_map(p
->task
), FALSE
);
2600 return (p
->p_csflags
& (CS_KILL
| CS_HARD
)) == 0;
2613 * XXX revisit locking when proc is no longer protected
2614 * by the kernel funnel...
2617 /* XXX for testing */
2620 p
->p_csflags
|= CS_KILL
;
2622 p
->p_csflags
|= CS_HARD
;
2624 /* CS_KILL triggers us to send a kill signal. Nothing else. */
2625 if (p
->p_csflags
& CS_KILL
) {
2628 printf("CODE SIGNING: cs_invalid_page(0x%llx): "
2629 "p=%d[%s] honoring CS_KILL\n",
2630 vaddr
, p
->p_pid
, p
->p_comm
);
2633 psignal(p
, SIGKILL
);
2637 /* CS_HARD means fail the mapping operation so the process stays valid. */
2638 if (p
->p_csflags
& CS_HARD
) {
2641 printf("CODE SIGNING: cs_invalid_page(0x%llx): "
2642 "p=%d[%s] honoring CS_HARD\n",
2643 vaddr
, p
->p_pid
, p
->p_comm
);
2647 if (p
->p_csflags
& CS_VALID
) {
2648 p
->p_csflags
&= ~CS_VALID
;
2651 cs_procs_invalidated
++;
2652 printf("CODE SIGNING: cs_invalid_page(0x%llx): "
2653 "p=%d[%s] clearing CS_VALID\n",
2654 vaddr
, p
->p_pid
, p
->p_comm
);
2666 proc_setregister(proc_t p
)
2669 p
->p_lflag
|= P_LREGISTER
;
2674 proc_resetregister(proc_t p
)
2677 p
->p_lflag
&= ~P_LREGISTER
;
2682 proc_pgrpid(proc_t p
)
2690 return current_proc()->p_pgrpid
;
2694 /* return control and action states */
2696 proc_getpcontrol(int pid
, int * pcontrolp
)
2703 if (pcontrolp
!= NULL
)
2704 *pcontrolp
= p
->p_pcaction
;
2711 proc_dopcontrol(proc_t p
, void *num_found
)
2717 pcontrol
= PROC_CONTROL_STATE(p
);
2719 if (PROC_ACTION_STATE(p
) ==0) {
2722 PROC_SETACTION_STATE(p
);
2724 printf("low swap: throttling pid %d (%s)\n", p
->p_pid
, p
->p_comm
);
2725 (*(int *)num_found
)++;
2729 PROC_SETACTION_STATE(p
);
2731 printf("low swap: suspending pid %d (%s)\n", p
->p_pid
, p
->p_comm
);
2732 task_suspend(p
->task
);
2733 (*(int *)num_found
)++;
2737 PROC_SETACTION_STATE(p
);
2739 printf("low swap: killing pid %d (%s)\n", p
->p_pid
, p
->p_comm
);
2740 psignal(p
, SIGKILL
);
2741 (*(int *)num_found
)++;
2751 return(PROC_RETURNED
);
2756 * Resume a throttled or suspended process. This is an internal interface that's only
2757 * used by the user level code that presents the GUI when we run out of swap space and
2758 * hence is restricted to processes with superuser privileges.
2762 proc_resetpcontrol(int pid
)
2768 if ((error
= suser(kauth_cred_get(), 0)))
2776 pcontrol
= PROC_CONTROL_STATE(p
);
2778 if(PROC_ACTION_STATE(p
) !=0) {
2781 PROC_RESETACTION_STATE(p
);
2783 printf("low swap: unthrottling pid %d (%s)\n", p
->p_pid
, p
->p_comm
);
2787 PROC_RESETACTION_STATE(p
);
2789 printf("low swap: resuming pid %d (%s)\n", p
->p_pid
, p
->p_comm
);
2790 task_resume(p
->task
);
2795 PROC_SETACTION_STATE(p
);
2797 printf("low swap: attempt to unkill pid %d (%s) ignored\n", p
->p_pid
, p
->p_comm
);
2813 * Return true if the specified process has an action state specified for it and it isn't
2814 * already in an action state and it's using more physical memory than the specified threshold.
2815 * Note: the memory_threshold argument is specified in bytes and is of type uint64_t.
2819 proc_pcontrol_filter(proc_t p
, void *memory_thresholdp
)
2822 return PROC_CONTROL_STATE(p
) && /* if there's an action state specified... */
2823 (PROC_ACTION_STATE(p
) == 0) && /* and we're not in the action state yet... */
2824 (get_task_resident_size(p
->task
) > *((uint64_t *)memory_thresholdp
)); /* and this proc is over the mem threshold, */
2825 /* then return true to take action on this proc */
2831 * Deal with the out of swap space condition. This routine gets called when
2832 * we want to swap something out but there's no more space left. Since this
2833 * creates a memory deadlock situtation, we need to take action to free up
2834 * some memory resources in order to prevent the system from hanging completely.
2835 * The action we take is based on what the system processes running at user level
2836 * have specified. Processes are marked in one of four categories: ones that
2837 * can be killed immediately, ones that should be suspended, ones that should
2838 * be throttled, and all the rest which are basically none of the above. Which
2839 * processes are marked as being in which category is a user level policy decision;
2840 * we just take action based on those decisions here.
2843 #define STARTING_PERCENTAGE 50 /* memory threshold expressed as a percentage */
2844 /* of physical memory */
2846 struct timeval last_no_space_action
= {0, 0};
2849 no_paging_space_action(void)
2852 uint64_t memory_threshold
;
2857 * Throttle how often we come through here. Once every 20 seconds should be plenty.
2862 if (now
.tv_sec
<= last_no_space_action
.tv_sec
+ 20)
2865 last_no_space_action
= now
;
2868 * Examine all processes and find those that have been marked to have some action
2869 * taken when swap space runs out. Of those processes, select one or more and
2870 * apply the specified action to them. The idea is to only take action against
2871 * a few processes rather than hitting too many at once. If the low swap condition
2872 * persists, this routine will get called again and we'll take action against more
2875 * Of the processes that have been marked, we choose which ones to take action
2876 * against according to how much physical memory they're presently using. We
2877 * start with the STARTING_THRESHOLD and any processes using more physical memory
2878 * than the percentage threshold will have action taken against it. If there
2879 * are no processes over the threshold, then the threshold is cut in half and we
2880 * look again for processes using more than this threshold. We continue in
2881 * this fashion until we find at least one process to take action against. This
2882 * iterative approach is less than ideally efficient, however we only get here
2883 * when the system is almost in a memory deadlock and is pretty much just
2884 * thrashing if it's doing anything at all. Therefore, the cpu overhead of
2885 * potentially multiple passes here probably isn't revelant.
2888 memory_threshold
= (sane_size
* STARTING_PERCENTAGE
) / 100; /* resident threshold in bytes */
2890 for (num_found
= 0; num_found
== 0; memory_threshold
= memory_threshold
/ 2) {
2891 proc_iterate(PROC_ALLPROCLIST
, proc_dopcontrol
, (void *)&num_found
, proc_pcontrol_filter
, (void *)&memory_threshold
);
2894 * If we just looked with memory_threshold == 0, then there's no need to iterate any further since
2895 * we won't find any eligible processes at this point.
2898 if (memory_threshold
== 0) {
2899 if (num_found
== 0) /* log that we couldn't do anything in this case */
2900 printf("low swap: unable to find any eligible processes to take action on\n");