2 * Copyright (c) 2005, 2010 Apple Computer, 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@
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/kernel.h>
36 #include <sys/malloc.h>
37 #include <sys/proc_internal.h>
38 #include <sys/kauth.h>
39 #include <sys/file_internal.h>
40 #include <sys/vnode_internal.h>
41 #include <sys/unistd.h>
43 #include <sys/ioctl.h>
44 #include <sys/namei.h>
46 #include <sys/disklabel.h>
48 #include <sys/sysctl.h>
50 #include <sys/aio_kern.h>
51 #include <sys/kern_memorystatus.h>
53 #include <security/audit/audit.h>
55 #include <mach/machine.h>
56 #include <mach/mach_types.h>
57 #include <mach/vm_param.h>
58 #include <kern/task.h>
59 #include <kern/lock.h>
60 #include <kern/kalloc.h>
61 #include <kern/assert.h>
62 #include <vm/vm_kern.h>
63 #include <vm/vm_map.h>
64 #include <mach/host_info.h>
65 #include <mach/task_info.h>
66 #include <mach/thread_info.h>
67 #include <mach/vm_region.h>
69 #include <sys/mount_internal.h>
70 #include <sys/proc_info.h>
71 #include <sys/bsdtask_info.h>
72 #include <sys/kdebug.h>
73 #include <sys/sysproto.h>
74 #include <sys/msgbuf.h>
76 #include <sys/msgbuf.h>
78 #include <machine/machine_routines.h>
80 #include <kern/ipc_misc.h>
82 #include <vm/vm_protos.h>
90 uint64_t get_dispatchqueue_offset_from_proc(void *);
91 int proc_info_internal(int callnum
, int pid
, int flavor
, uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
);
93 /* protos for proc_info calls */
94 int proc_listpids(uint32_t type
, uint32_t tyoneinfo
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
);
95 int proc_pidinfo(int pid
, int flavor
, uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
);
96 int proc_pidfdinfo(int pid
, int flavor
,int fd
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
);
97 int proc_kernmsgbuf(user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
);
98 int proc_setcontrol(int pid
, int flavor
, uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
);
99 int proc_pidfileportinfo(int pid
, int flavor
, mach_port_name_t name
, user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
);
100 int proc_dirtycontrol(int pid
, int flavor
, uint64_t arg
, int32_t * retval
);
101 int proc_terminate(int pid
, int32_t * retval
);
103 /* protos for procpidinfo calls */
104 int proc_pidfdlist(proc_t p
, user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
);
105 int proc_pidbsdinfo(proc_t p
, struct proc_bsdinfo
*pbsd
, int zombie
);
106 int proc_pidshortbsdinfo(proc_t p
, struct proc_bsdshortinfo
*pbsd_shortp
, int zombie
);
107 int proc_pidtaskinfo(proc_t p
, struct proc_taskinfo
*ptinfo
);
108 int proc_pidallinfo(proc_t p
, int flavor
, uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
);
109 int proc_pidthreadinfo(proc_t p
, uint64_t arg
, int thuniqueid
, struct proc_threadinfo
*pthinfo
);
110 int proc_pidthreadpathinfo(proc_t p
, uint64_t arg
, struct proc_threadwithpathinfo
*pinfo
);
111 int proc_pidlistthreads(proc_t p
, user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
);
112 int proc_pidregioninfo(proc_t p
, uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
);
113 int proc_pidregionpathinfo(proc_t p
, uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
);
114 int proc_pidvnodepathinfo(proc_t p
, uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
);
115 int proc_pidpathinfo(proc_t p
, uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
);
116 int proc_pidworkqueueinfo(proc_t p
, struct proc_workqueueinfo
*pwqinfo
);
117 int proc_pidfileportlist(proc_t p
, user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
);
120 /* protos for proc_pidfdinfo calls */
121 int pid_vnodeinfo(vnode_t vp
, uint32_t vid
, struct fileproc
* fp
, int closeonexec
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
);
122 int pid_vnodeinfopath(vnode_t vp
, uint32_t vid
, struct fileproc
* fp
, int closeonexec
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
);
123 int pid_socketinfo(socket_t so
, struct fileproc
*fp
, int closeonexec
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
);
124 int pid_pseminfo(struct psemnode
* psem
, struct fileproc
* fp
, int closeonexec
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
);
125 int pid_pshminfo(struct pshmnode
* pshm
, struct fileproc
* fp
, int closeonexec
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
);
126 int pid_pipeinfo(struct pipe
* p
, struct fileproc
* fp
, int closeonexec
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
);
127 int pid_kqueueinfo(struct kqueue
* kq
, struct fileproc
* fp
, int closeonexec
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
);
128 int pid_atalkinfo(struct atalk
* at
, struct fileproc
* fp
, int closeonexec
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
);
131 /* protos for misc */
133 void proc_dirty_start(struct proc
*p
);
134 void proc_dirty_end(struct proc
*p
);
136 int fill_vnodeinfo(vnode_t vp
, struct vnode_info
*vinfo
);
137 void fill_fileinfo(struct fileproc
* fp
, int closeonexec
, struct proc_fileinfo
* finfo
);
138 static int proc_security_policy(proc_t p
);
139 static void munge_vinfo_stat(struct stat64
*sbp
, struct vinfo_stat
*vsbp
);
141 extern int cansignal(struct proc
*, kauth_cred_t
, struct proc
*, int, int);
143 uint64_t get_dispatchqueue_offset_from_proc(void *p
)
146 proc_t pself
= (proc_t
)p
;
147 return (pself
->p_dispatchqueue_offset
);
153 /***************************** proc_info ********************/
156 proc_info(__unused
struct proc
*p
, struct proc_info_args
* uap
, int32_t *retval
)
158 return(proc_info_internal(uap
->callnum
, uap
->pid
, uap
->flavor
, uap
->arg
, uap
->buffer
, uap
->buffersize
, retval
));
163 proc_info_internal(int callnum
, int pid
, int flavor
, uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
)
167 case 1: /* proc_listpids */
168 /* pid contains type and flavor contains typeinfo */
169 return(proc_listpids(pid
, flavor
, buffer
, buffersize
, retval
));
170 case 2: /* proc_pidinfo */
171 return(proc_pidinfo(pid
, flavor
, arg
, buffer
, buffersize
, retval
));
172 case 3: /* proc_pidfdinfo */
173 return(proc_pidfdinfo(pid
, flavor
, (int)arg
, buffer
, buffersize
, retval
));
174 case 4: /* proc_kernmsgbuf */
175 return(proc_kernmsgbuf(buffer
, buffersize
, retval
));
176 case 5: /* set on self properties proc_setcontrol */
177 return(proc_setcontrol(pid
, flavor
, arg
, buffer
, buffersize
, retval
));
178 case 6: /* proc_pidfileportinfo */
179 return(proc_pidfileportinfo(pid
, flavor
, (mach_port_name_t
)arg
, buffer
, buffersize
, retval
));
180 case 7: /* proc_terminate */
181 return(proc_terminate(pid
, retval
));
182 case 8: /* proc_dirtycontrol */
183 return(proc_dirtycontrol(pid
, flavor
, arg
, retval
));
191 /******************* proc_listpids routine ****************/
193 proc_listpids(uint32_t type
, uint32_t typeinfo
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
)
195 int numprocs
, wantpids
;
202 struct proclist
*current_list
;
204 /* if the buffer is null, return num of procs */
205 if (buffer
== (user_addr_t
)0) {
206 *retval
= ((nprocs
+20) * sizeof(int));
210 if (buffersize
< sizeof(int)) {
213 wantpids
= buffersize
/sizeof(int);
214 numprocs
= nprocs
+20;
215 if (numprocs
> wantpids
)
218 kbuf
= (char *)kalloc((vm_size_t
)(numprocs
* sizeof(int)));
221 bzero(kbuf
, sizeof(int));
228 current_list
= &allproc
;
230 LIST_FOREACH(p
, current_list
, p_list
) {
234 if (p
->p_pgrpid
!= (pid_t
)typeinfo
)
238 if ((p
->p_ppid
!= (pid_t
)typeinfo
) && (((p
->p_lflag
& P_LTRACED
) == 0) || (p
->p_oppid
!= (pid_t
)typeinfo
)))
246 /* racy but list lock is held */
247 if ((p
->p_flag
& P_CONTROLT
) == 0 ||
248 (p
->p_pgrp
== NULL
) || (p
->p_pgrp
->pg_session
== NULL
) ||
249 (tp
= SESSION_TP(p
->p_pgrp
->pg_session
)) == TTY_NULL
||
250 tp
->t_dev
!= (dev_t
)typeinfo
)
254 if (p
->p_ucred
== NULL
)
257 kauth_cred_t my_cred
;
260 my_cred
= kauth_cred_proc_ref(p
);
261 uid
= kauth_cred_getuid(my_cred
);
262 kauth_cred_unref(&my_cred
);
263 if (uid
!= (uid_t
)typeinfo
)
268 if (p
->p_ucred
== NULL
)
271 kauth_cred_t my_cred
;
274 my_cred
= kauth_cred_proc_ref(p
);
275 uid
= kauth_cred_getruid(my_cred
);
276 kauth_cred_unref(&my_cred
);
277 if (uid
!= (uid_t
)typeinfo
)
294 if ((n
< numprocs
) && (current_list
== &allproc
)) {
295 current_list
= &zombproc
;
302 error
= copyout((caddr_t
)ptr
, buffer
, n
* sizeof(int));
304 *retval
= (n
* sizeof(int));
305 kfree((void *)kbuf
, (vm_size_t
)(numprocs
* sizeof(int)));
311 /********************************** proc_pidinfo routines ********************************/
314 proc_pidfdlist(proc_t p
, user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
)
318 struct proc_fdinfo
* pfd
;
319 struct fileproc
* fp
;
324 numfds
= p
->p_fd
->fd_nfiles
;
326 if (buffer
== (user_addr_t
) 0) {
328 *retval
= (numfds
* sizeof(struct proc_fdinfo
));
332 /* buffersize is big enough atleast for one struct */
333 needfds
= buffersize
/sizeof(struct proc_fdinfo
);
335 if (numfds
> needfds
)
338 kbuf
= (char *)kalloc((vm_size_t
)(numfds
* sizeof(struct proc_fdinfo
)));
341 bzero(kbuf
, numfds
* sizeof(struct proc_fdinfo
));
345 pfd
= (struct proc_fdinfo
*)kbuf
;
347 for (n
= 0; ((n
< numfds
) && (n
< p
->p_fd
->fd_nfiles
)); n
++) {
348 if (((fp
= p
->p_fd
->fd_ofiles
[n
]) != 0)
349 && ((p
->p_fd
->fd_ofileflags
[n
] & UF_RESERVED
) == 0)) {
351 pfd
->proc_fdtype
= fp
->f_fglob
->fg_type
;
358 error
= copyout(kbuf
, buffer
, count
* sizeof(struct proc_fdinfo
));
359 kfree((void *)kbuf
, (vm_size_t
)(numfds
* sizeof(struct proc_fdinfo
)));
361 *retval
= (count
* sizeof(struct proc_fdinfo
));
366 * Helper functions for proc_pidfileportlist.
369 proc_fileport_count(__unused mach_port_name_t name
,
370 __unused
struct fileglob
*fg
, void *arg
)
372 uint32_t *counter
= arg
;
378 struct fileport_fdtype_args
{
379 struct proc_fileportinfo
*ffa_pfi
;
380 struct proc_fileportinfo
*ffa_pfi_end
;
384 proc_fileport_fdtype(mach_port_name_t name
, struct fileglob
*fg
, void *arg
)
386 struct fileport_fdtype_args
*ffa
= arg
;
388 if (ffa
->ffa_pfi
!= ffa
->ffa_pfi_end
) {
389 ffa
->ffa_pfi
->proc_fdtype
= fg
->fg_type
;
390 ffa
->ffa_pfi
->proc_fileport
= name
;
392 return (0); /* keep walking */
394 return (-1); /* stop the walk! */
398 proc_pidfileportlist(proc_t p
,
399 user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
)
403 struct proc_fileportinfo
*pfi
;
404 uint32_t needfileports
, numfileports
;
405 struct fileport_fdtype_args ffa
;
408 needfileports
= buffersize
/ sizeof (*pfi
);
409 if ((user_addr_t
)0 == buffer
|| needfileports
> (uint32_t)maxfiles
) {
411 * Either (i) the user is asking for a fileport count,
412 * or (ii) the number of fileports they're asking for is
413 * larger than the maximum number of open files (!); count
414 * them to bound subsequent heap allocations.
417 switch (fileport_walk(p
->task
,
418 proc_fileport_count
, &numfileports
)) {
421 case KERN_RESOURCE_SHORTAGE
:
423 case KERN_INVALID_TASK
:
429 if (numfileports
== 0) {
430 *retval
= 0; /* none at all, bail */
433 if ((user_addr_t
)0 == buffer
) {
434 numfileports
+= 20; /* accelerate convergence */
435 *retval
= numfileports
* sizeof (*pfi
);
438 if (needfileports
> numfileports
)
439 needfileports
= numfileports
;
442 assert(buffersize
>= PROC_PIDLISTFILEPORTS_SIZE
);
444 kbufsize
= (vm_size_t
)needfileports
* sizeof (*pfi
);
445 pfi
= kbuf
= kalloc(kbufsize
);
448 bzero(kbuf
, kbufsize
);
451 ffa
.ffa_pfi_end
= pfi
+ needfileports
;
453 switch (fileport_walk(p
->task
, proc_fileport_fdtype
, &ffa
)) {
457 if ((numfileports
= pfi
- (typeof(pfi
))kbuf
) == 0)
459 if (numfileports
> needfileports
)
460 panic("more fileports returned than requested");
461 error
= copyout(kbuf
, buffer
, numfileports
* sizeof (*pfi
));
463 case KERN_RESOURCE_SHORTAGE
:
466 case KERN_INVALID_TASK
:
473 kfree(kbuf
, kbufsize
);
475 *retval
= numfileports
* sizeof (*pfi
);
480 proc_pidbsdinfo(proc_t p
, struct proc_bsdinfo
* pbsd
, int zombie
)
482 register struct tty
*tp
;
483 struct session
*sessionp
= NULL
;
485 kauth_cred_t my_cred
;
488 sessionp
= proc_session(p
);
490 my_cred
= kauth_cred_proc_ref(p
);
491 bzero(pbsd
, sizeof(struct proc_bsdinfo
));
492 pbsd
->pbi_status
= p
->p_stat
;
493 pbsd
->pbi_xstatus
= p
->p_xstat
;
494 pbsd
->pbi_pid
= p
->p_pid
;
495 pbsd
->pbi_ppid
= p
->p_ppid
;
496 pbsd
->pbi_uid
= kauth_cred_getuid(my_cred
);
497 pbsd
->pbi_gid
= kauth_cred_getgid(my_cred
);
498 pbsd
->pbi_ruid
= kauth_cred_getruid(my_cred
);
499 pbsd
->pbi_rgid
= kauth_cred_getrgid(my_cred
);
500 pbsd
->pbi_svuid
= kauth_cred_getsvuid(my_cred
);
501 pbsd
->pbi_svgid
= kauth_cred_getsvgid(my_cred
);
502 kauth_cred_unref(&my_cred
);
504 pbsd
->pbi_nice
= p
->p_nice
;
505 pbsd
->pbi_start_tvsec
= p
->p_start
.tv_sec
;
506 pbsd
->pbi_start_tvusec
= p
->p_start
.tv_usec
;
507 bcopy(&p
->p_comm
, &pbsd
->pbi_comm
[0], MAXCOMLEN
);
508 pbsd
->pbi_comm
[MAXCOMLEN
- 1] = '\0';
509 bcopy(&p
->p_name
, &pbsd
->pbi_name
[0], 2*MAXCOMLEN
);
510 pbsd
->pbi_name
[(2*MAXCOMLEN
) - 1] = '\0';
513 if ((p
->p_flag
& P_SYSTEM
) == P_SYSTEM
)
514 pbsd
->pbi_flags
|= PROC_FLAG_SYSTEM
;
515 if ((p
->p_lflag
& P_LTRACED
) == P_LTRACED
)
516 pbsd
->pbi_flags
|= PROC_FLAG_TRACED
;
517 if ((p
->p_lflag
& P_LEXIT
) == P_LEXIT
)
518 pbsd
->pbi_flags
|= PROC_FLAG_INEXIT
;
519 if ((p
->p_lflag
& P_LPPWAIT
) == P_LPPWAIT
)
520 pbsd
->pbi_flags
|= PROC_FLAG_PPWAIT
;
521 if ((p
->p_flag
& P_LP64
) == P_LP64
)
522 pbsd
->pbi_flags
|= PROC_FLAG_LP64
;
523 if ((p
->p_flag
& P_CONTROLT
) == P_CONTROLT
)
524 pbsd
->pbi_flags
|= PROC_FLAG_CONTROLT
;
525 if ((p
->p_flag
& P_THCWD
) == P_THCWD
)
526 pbsd
->pbi_flags
|= PROC_FLAG_THCWD
;
527 if ((p
->p_flag
& P_SUGID
) == P_SUGID
)
528 pbsd
->pbi_flags
|= PROC_FLAG_PSUGID
;
529 if ((p
->p_flag
& P_EXEC
) == P_EXEC
)
530 pbsd
->pbi_flags
|= PROC_FLAG_EXEC
;
532 if (sessionp
!= SESSION_NULL
) {
533 if (SESS_LEADER(p
, sessionp
))
534 pbsd
->pbi_flags
|= PROC_FLAG_SLEADER
;
535 if (sessionp
->s_ttyvp
)
536 pbsd
->pbi_flags
|= PROC_FLAG_CTTY
;
540 if ((p
->p_flag
& P_DELAYIDLESLEEP
) == P_DELAYIDLESLEEP
)
541 pbsd
->pbi_flags
|= PROC_FLAG_DELAYIDLESLEEP
;
542 #endif /* !CONFIG_EMBEDDED */
544 switch(PROC_CONTROL_STATE(p
)) {
546 pbsd
->pbi_flags
|= PROC_FLAG_PC_THROTTLE
;
549 pbsd
->pbi_flags
|= PROC_FLAG_PC_SUSP
;
552 pbsd
->pbi_flags
|= PROC_FLAG_PC_KILL
;
556 switch(PROC_ACTION_STATE(p
)) {
558 pbsd
->pbi_flags
|= PROC_FLAG_PA_THROTTLE
;
561 pbsd
->pbi_flags
|= PROC_FLAG_PA_SUSP
;
565 /* if process is a zombie skip bg state */
566 if ((zombie
== 0) && (p
->p_stat
!= SZOMB
) && (p
->task
!= TASK_NULL
))
567 proc_get_darwinbgstate(p
->task
, &pbsd
->pbi_flags
);
570 pbsd
->pbi_nfiles
= p
->p_fd
->fd_nfiles
;
572 pbsd
->e_tdev
= NODEV
;
573 if (pg
!= PGRP_NULL
) {
574 pbsd
->pbi_pgid
= p
->p_pgrpid
;
575 pbsd
->pbi_pjobc
= pg
->pg_jobc
;
576 if ((p
->p_flag
& P_CONTROLT
) && (sessionp
!= SESSION_NULL
) && (tp
= SESSION_TP(sessionp
))) {
577 pbsd
->e_tdev
= tp
->t_dev
;
578 pbsd
->e_tpgid
= sessionp
->s_ttypgrpid
;
581 if (sessionp
!= SESSION_NULL
)
582 session_rele(sessionp
);
591 proc_pidshortbsdinfo(proc_t p
, struct proc_bsdshortinfo
* pbsd_shortp
, int zombie
)
593 bzero(pbsd_shortp
, sizeof(struct proc_bsdshortinfo
));
594 pbsd_shortp
->pbsi_pid
= p
->p_pid
;
595 pbsd_shortp
->pbsi_ppid
= p
->p_ppid
;
596 pbsd_shortp
->pbsi_pgid
= p
->p_pgrpid
;
597 pbsd_shortp
->pbsi_status
= p
->p_stat
;
598 bcopy(&p
->p_comm
, &pbsd_shortp
->pbsi_comm
[0], MAXCOMLEN
);
599 pbsd_shortp
->pbsi_comm
[MAXCOMLEN
- 1] = '\0';
601 pbsd_shortp
->pbsi_flags
= 0;
602 if ((p
->p_flag
& P_SYSTEM
) == P_SYSTEM
)
603 pbsd_shortp
->pbsi_flags
|= PROC_FLAG_SYSTEM
;
604 if ((p
->p_lflag
& P_LTRACED
) == P_LTRACED
)
605 pbsd_shortp
->pbsi_flags
|= PROC_FLAG_TRACED
;
606 if ((p
->p_lflag
& P_LEXIT
) == P_LEXIT
)
607 pbsd_shortp
->pbsi_flags
|= PROC_FLAG_INEXIT
;
608 if ((p
->p_lflag
& P_LPPWAIT
) == P_LPPWAIT
)
609 pbsd_shortp
->pbsi_flags
|= PROC_FLAG_PPWAIT
;
610 if ((p
->p_flag
& P_LP64
) == P_LP64
)
611 pbsd_shortp
->pbsi_flags
|= PROC_FLAG_LP64
;
612 if ((p
->p_flag
& P_CONTROLT
) == P_CONTROLT
)
613 pbsd_shortp
->pbsi_flags
|= PROC_FLAG_CONTROLT
;
614 if ((p
->p_flag
& P_THCWD
) == P_THCWD
)
615 pbsd_shortp
->pbsi_flags
|= PROC_FLAG_THCWD
;
616 if ((p
->p_flag
& P_SUGID
) == P_SUGID
)
617 pbsd_shortp
->pbsi_flags
|= PROC_FLAG_PSUGID
;
618 if ((p
->p_flag
& P_EXEC
) == P_EXEC
)
619 pbsd_shortp
->pbsi_flags
|= PROC_FLAG_EXEC
;
621 if ((p
->p_flag
& P_DELAYIDLESLEEP
) == P_DELAYIDLESLEEP
)
622 pbsd_shortp
->pbsi_flags
|= PROC_FLAG_DELAYIDLESLEEP
;
623 #endif /* !CONFIG_EMBEDDED */
625 switch(PROC_CONTROL_STATE(p
)) {
627 pbsd_shortp
->pbsi_flags
|= PROC_FLAG_PC_THROTTLE
;
630 pbsd_shortp
->pbsi_flags
|= PROC_FLAG_PC_SUSP
;
633 pbsd_shortp
->pbsi_flags
|= PROC_FLAG_PC_KILL
;
637 switch(PROC_ACTION_STATE(p
)) {
639 pbsd_shortp
->pbsi_flags
|= PROC_FLAG_PA_THROTTLE
;
642 pbsd_shortp
->pbsi_flags
|= PROC_FLAG_PA_SUSP
;
646 /* if process is a zombie skip bg state */
647 if ((zombie
== 0) && (p
->p_stat
!= SZOMB
) && (p
->task
!= TASK_NULL
))
648 proc_get_darwinbgstate(p
->task
, &pbsd_shortp
->pbsi_flags
);
650 pbsd_shortp
->pbsi_uid
= p
->p_uid
;
651 pbsd_shortp
->pbsi_gid
= p
->p_gid
;
652 pbsd_shortp
->pbsi_ruid
= p
->p_ruid
;
653 pbsd_shortp
->pbsi_rgid
= p
->p_rgid
;
654 pbsd_shortp
->pbsi_svuid
= p
->p_svuid
;
655 pbsd_shortp
->pbsi_svgid
= p
->p_svgid
;
661 proc_pidtaskinfo(proc_t p
, struct proc_taskinfo
* ptinfo
)
667 bzero(ptinfo
, sizeof(struct proc_taskinfo
));
668 fill_taskprocinfo(task
, (struct proc_taskinfo_internal
*)ptinfo
);
676 proc_pidthreadinfo(proc_t p
, uint64_t arg
, int thuniqueid
, struct proc_threadinfo
*pthinfo
)
679 uint64_t threadaddr
= (uint64_t)arg
;
681 bzero(pthinfo
, sizeof(struct proc_threadinfo
));
683 error
= fill_taskthreadinfo(p
->task
, threadaddr
, thuniqueid
, (struct proc_threadinfo_internal
*)pthinfo
, NULL
, NULL
);
692 bsd_getthreadname(void *uth
, char *buffer
)
694 struct uthread
*ut
= (struct uthread
*)uth
;
696 bcopy(ut
->pth_name
,buffer
,MAXTHREADNAMESIZE
);
700 bsd_threadcdir(void * uth
, void *vptr
, int *vidp
)
702 struct uthread
* ut
= (struct uthread
*)uth
;
704 vnode_t
*vpp
= (vnode_t
*)vptr
;
718 proc_pidthreadpathinfo(proc_t p
, uint64_t arg
, struct proc_threadwithpathinfo
*pinfo
)
723 uint64_t threadaddr
= (uint64_t)arg
;
726 bzero(pinfo
, sizeof(struct proc_threadwithpathinfo
));
728 error
= fill_taskthreadinfo(p
->task
, threadaddr
, 0, (struct proc_threadinfo_internal
*)&pinfo
->pt
, (void *)&vp
, &vid
);
732 if ((vp
!= NULLVP
) && ((vnode_getwithvid(vp
, vid
)) == 0)) {
733 error
= fill_vnodeinfo(vp
, &pinfo
->pvip
.vip_vi
) ;
736 vn_getpath(vp
, &pinfo
->pvip
.vip_path
[0], &count
);
737 pinfo
->pvip
.vip_path
[MAXPATHLEN
-1] = 0;
747 proc_pidlistthreads(proc_t p
, user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
)
756 count
= buffersize
/(sizeof(uint64_t));
757 numthreads
= get_numthreads(p
->task
);
761 if (numthreads
> count
)
764 kbuf
= (void *)kalloc(numthreads
* sizeof(uint64_t));
767 bzero(kbuf
, numthreads
* sizeof(uint64_t));
769 ret
= fill_taskthreadlist(p
->task
, kbuf
, numthreads
);
771 error
= copyout(kbuf
, buffer
, ret
);
772 kfree(kbuf
, numthreads
* sizeof(uint64_t));
781 proc_pidregioninfo(proc_t p
, uint64_t arg
, user_addr_t buffer
, __unused
uint32_t buffersize
, int32_t *retval
)
783 struct proc_regioninfo preginfo
;
786 bzero(&preginfo
, sizeof(struct proc_regioninfo
));
787 ret
= fill_procregioninfo( p
->task
, arg
, (struct proc_regioninfo_internal
*)&preginfo
, (uintptr_t *)0, (uint32_t *)0);
790 error
= copyout(&preginfo
, buffer
, sizeof(struct proc_regioninfo
));
792 *retval
= sizeof(struct proc_regioninfo
);
798 proc_pidregionpathinfo(proc_t p
, uint64_t arg
, user_addr_t buffer
, __unused
uint32_t buffersize
, int32_t *retval
)
800 struct proc_regionwithpathinfo preginfo
;
802 uintptr_t vnodeaddr
= 0;
807 bzero(&preginfo
, sizeof(struct proc_regionwithpathinfo
));
809 ret
= fill_procregioninfo( p
->task
, arg
, (struct proc_regioninfo_internal
*)&preginfo
.prp_prinfo
, (uintptr_t *)&vnodeaddr
, (uint32_t *)&vnodeid
);
813 vp
= (vnode_t
)vnodeaddr
;
814 if ((vnode_getwithvid(vp
, vnodeid
)) == 0) {
815 /* FILL THE VNODEINFO */
816 error
= fill_vnodeinfo(vp
, &preginfo
.prp_vip
.vip_vi
);
818 vn_getpath(vp
, &preginfo
.prp_vip
.vip_path
[0], &count
);
819 /* Always make sure it is null terminated */
820 preginfo
.prp_vip
.vip_path
[MAXPATHLEN
-1] = 0;
824 error
= copyout(&preginfo
, buffer
, sizeof(struct proc_regionwithpathinfo
));
826 *retval
= sizeof(struct proc_regionwithpathinfo
);
831 * Path is relative to current process directory; may different from current
835 proc_pidvnodepathinfo(proc_t p
, __unused
uint64_t arg
, user_addr_t buffer
, __unused
uint32_t buffersize
, int32_t *retval
)
837 struct proc_vnodepathinfo pvninfo
;
839 vnode_t vncdirvp
= NULLVP
;
841 vnode_t vnrdirvp
= NULLVP
;
845 bzero(&pvninfo
, sizeof(struct proc_vnodepathinfo
));
848 if (p
->p_fd
->fd_cdir
) {
849 vncdirvp
= p
->p_fd
->fd_cdir
;
850 vncdirid
= p
->p_fd
->fd_cdir
->v_id
;
852 if (p
->p_fd
->fd_rdir
) {
853 vnrdirvp
= p
->p_fd
->fd_rdir
;
854 vnrdirid
= p
->p_fd
->fd_rdir
->v_id
;
858 if (vncdirvp
!= NULLVP
) {
859 if ((error
= vnode_getwithvid(vncdirvp
, vncdirid
)) == 0) {
860 /* FILL THE VNODEINFO */
861 error
= fill_vnodeinfo(vncdirvp
, &pvninfo
.pvi_cdir
.vip_vi
);
864 vn_getpath(vncdirvp
, &pvninfo
.pvi_cdir
.vip_path
[0], &count
);
865 pvninfo
.pvi_cdir
.vip_path
[MAXPATHLEN
-1] = 0;
873 if ((error
== 0) && (vnrdirvp
!= NULLVP
)) {
874 if ((error
= vnode_getwithvid(vnrdirvp
, vnrdirid
)) == 0) {
875 /* FILL THE VNODEINFO */
876 error
= fill_vnodeinfo(vnrdirvp
, &pvninfo
.pvi_rdir
.vip_vi
);
879 vn_getpath(vnrdirvp
, &pvninfo
.pvi_rdir
.vip_path
[0], &count
);
880 pvninfo
.pvi_rdir
.vip_path
[MAXPATHLEN
-1] = 0;
888 error
= copyout(&pvninfo
, buffer
, sizeof(struct proc_vnodepathinfo
));
890 *retval
= sizeof(struct proc_vnodepathinfo
);
897 proc_pidpathinfo(proc_t p
, __unused
uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, __unused
int32_t *retval
)
901 vnode_t nvp
= NULLVP
;
902 int len
= buffersize
;
910 buf
= (char *)kalloc(buffersize
);
915 vid
= vnode_vid(tvp
);
916 error
= vnode_getwithvid(tvp
, vid
);
918 error
= vn_getpath_fsenter(tvp
, buf
, &len
);
921 error
= vnode_lookup(buf
, 0, &nvp
, vfs_context_current());
922 if ((error
== 0) && ( nvp
!= NULLVP
))
925 error
= copyout(buf
, buffer
, len
);
929 kfree(buf
, buffersize
);
935 proc_pidworkqueueinfo(proc_t p
, struct proc_workqueueinfo
*pwqinfo
)
939 bzero(pwqinfo
, sizeof(struct proc_workqueueinfo
));
941 error
= fill_procworkqueue(p
, pwqinfo
);
948 /********************************** proc_pidinfo ********************************/
952 proc_pidinfo(int pid
, int flavor
, uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
)
954 struct proc
* p
= PROC_NULL
;
958 int refheld
= 0, shortversion
= 0;
964 case PROC_PIDLISTFDS
:
965 size
= PROC_PIDLISTFD_SIZE
;
966 if (buffer
== (user_addr_t
)0)
969 case PROC_PIDTBSDINFO
:
970 size
= PROC_PIDTBSDINFO_SIZE
;
972 case PROC_PIDTASKINFO
:
973 size
= PROC_PIDTASKINFO_SIZE
;
975 case PROC_PIDTASKALLINFO
:
976 size
= PROC_PIDTASKALLINFO_SIZE
;
978 case PROC_PIDTHREADINFO
:
979 size
= PROC_PIDTHREADINFO_SIZE
;
981 case PROC_PIDLISTTHREADS
:
982 size
= PROC_PIDLISTTHREADS_SIZE
;
984 case PROC_PIDREGIONINFO
:
985 size
= PROC_PIDREGIONINFO_SIZE
;
987 case PROC_PIDREGIONPATHINFO
:
988 size
= PROC_PIDREGIONPATHINFO_SIZE
;
990 case PROC_PIDVNODEPATHINFO
:
991 size
= PROC_PIDVNODEPATHINFO_SIZE
;
993 case PROC_PIDTHREADPATHINFO
:
994 size
= PROC_PIDTHREADPATHINFO_SIZE
;
996 case PROC_PIDPATHINFO
:
999 case PROC_PIDWORKQUEUEINFO
:
1000 /* kernel does not have workq info */
1004 size
= PROC_PIDWORKQUEUEINFO_SIZE
;
1006 case PROC_PIDT_SHORTBSDINFO
:
1007 size
= PROC_PIDT_SHORTBSDINFO_SIZE
;
1009 case PROC_PIDLISTFILEPORTS
:
1010 size
= PROC_PIDLISTFILEPORTS_SIZE
;
1011 if (buffer
== (user_addr_t
)0)
1014 case PROC_PIDTHREADID64INFO
:
1015 size
= PROC_PIDTHREADID64INFO_SIZE
;
1021 if (buffersize
< size
)
1024 if ((flavor
== PROC_PIDPATHINFO
) && (buffersize
> PROC_PIDPATHINFO_MAXSIZE
)) {
1028 if ((flavor
!= PROC_PIDTBSDINFO
) && (flavor
!= PROC_PIDPATHINFO
) && (flavor
!= PROC_PIDT_SHORTBSDINFO
)) {
1029 if ((p
= proc_find(pid
)) == PROC_NULL
) {
1035 /* Do we have permission to look into this ? */
1036 if ((error
= proc_security_policy(p
)) != 0) {
1042 case PROC_PIDLISTFDS
: {
1043 error
= proc_pidfdlist(p
, buffer
, buffersize
, retval
);
1047 case PROC_PIDT_SHORTBSDINFO
:
1049 case PROC_PIDTBSDINFO
: {
1050 struct proc_bsdinfo pbsd
;
1051 struct proc_bsdshortinfo pbsd_short
;
1057 if (p
== PROC_NULL
) {
1059 p
= proc_find_zombref(pid
);
1067 /* Do we have permission to look into this ? */
1068 if ((flavor
!= PROC_PIDT_SHORTBSDINFO
) && ((error
= proc_security_policy(p
)) != 0)) {
1071 proc_drop_zombref(p
);
1077 if (shortversion
!= 0) {
1078 error
= proc_pidshortbsdinfo(p
, &pbsd_short
, zombie
);
1080 error
= proc_pidbsdinfo(p
, &pbsd
, zombie
);
1084 proc_drop_zombref(p
);
1089 if (shortversion
!= 0) {
1090 error
= copyout(&pbsd_short
, buffer
, sizeof(struct proc_bsdshortinfo
));
1092 *retval
= sizeof(struct proc_bsdshortinfo
);
1094 error
= copyout(&pbsd
, buffer
, sizeof(struct proc_bsdinfo
));
1096 *retval
= sizeof(struct proc_bsdinfo
);
1102 case PROC_PIDTASKINFO
: {
1103 struct proc_taskinfo ptinfo
;
1105 error
= proc_pidtaskinfo(p
, &ptinfo
);
1107 error
= copyout(&ptinfo
, buffer
, sizeof(struct proc_taskinfo
));
1109 *retval
= sizeof(struct proc_taskinfo
);
1114 case PROC_PIDTASKALLINFO
: {
1115 struct proc_taskallinfo pall
;
1117 error
= proc_pidbsdinfo(p
, &pall
.pbsd
, 0);
1118 error
= proc_pidtaskinfo(p
, &pall
.ptinfo
);
1120 error
= copyout(&pall
, buffer
, sizeof(struct proc_taskallinfo
));
1122 *retval
= sizeof(struct proc_taskallinfo
);
1127 case PROC_PIDTHREADID64INFO
:
1129 case PROC_PIDTHREADINFO
:{
1130 struct proc_threadinfo pthinfo
;
1132 error
= proc_pidthreadinfo(p
, arg
, thuniqueid
, &pthinfo
);
1134 error
= copyout(&pthinfo
, buffer
, sizeof(struct proc_threadinfo
));
1136 *retval
= sizeof(struct proc_threadinfo
);
1141 case PROC_PIDLISTTHREADS
:{
1142 error
= proc_pidlistthreads(p
, buffer
, buffersize
, retval
);
1146 case PROC_PIDREGIONINFO
:{
1147 error
= proc_pidregioninfo(p
, arg
, buffer
, buffersize
, retval
);
1152 case PROC_PIDREGIONPATHINFO
:{
1153 error
= proc_pidregionpathinfo(p
, arg
, buffer
, buffersize
, retval
);
1157 case PROC_PIDVNODEPATHINFO
:{
1158 error
= proc_pidvnodepathinfo(p
, arg
, buffer
, buffersize
, retval
);
1163 case PROC_PIDTHREADPATHINFO
:{
1164 struct proc_threadwithpathinfo pinfo
;
1166 error
= proc_pidthreadpathinfo(p
, arg
, &pinfo
);
1168 error
= copyout((caddr_t
)&pinfo
, buffer
, sizeof(struct proc_threadwithpathinfo
));
1170 *retval
= sizeof(struct proc_threadwithpathinfo
);
1175 case PROC_PIDPATHINFO
: {
1177 if (p
== PROC_NULL
) {
1182 error
= proc_pidpathinfo(p
, arg
, buffer
, buffersize
, retval
);
1187 case PROC_PIDWORKQUEUEINFO
:{
1188 struct proc_workqueueinfo pwqinfo
;
1190 error
= proc_pidworkqueueinfo(p
, &pwqinfo
);
1192 error
= copyout(&pwqinfo
, buffer
, sizeof(struct proc_workqueueinfo
));
1194 *retval
= sizeof(struct proc_workqueueinfo
);
1199 case PROC_PIDLISTFILEPORTS
: {
1200 error
= proc_pidfileportlist(p
, buffer
, buffersize
,
1217 pid_vnodeinfo(vnode_t vp
, uint32_t vid
, struct fileproc
* fp
, int closeonexec
, user_addr_t buffer
, __unused
uint32_t buffersize
, int32_t * retval
)
1219 struct vnode_fdinfo vfi
;
1222 if ((error
= vnode_getwithvid(vp
, vid
)) != 0) {
1225 bzero(&vfi
, sizeof(struct vnode_fdinfo
));
1226 fill_fileinfo(fp
, closeonexec
, &vfi
.pfi
);
1227 error
= fill_vnodeinfo(vp
, &vfi
.pvi
);
1230 error
= copyout((caddr_t
)&vfi
, buffer
, sizeof(struct vnode_fdinfo
));
1232 *retval
= sizeof(struct vnode_fdinfo
);
1238 pid_vnodeinfopath(vnode_t vp
, uint32_t vid
, struct fileproc
* fp
, int closeonexec
, user_addr_t buffer
, __unused
uint32_t buffersize
, int32_t * retval
)
1240 struct vnode_fdinfowithpath vfip
;
1241 int count
, error
= 0;
1243 if ((error
= vnode_getwithvid(vp
, vid
)) != 0) {
1246 bzero(&vfip
, sizeof(struct vnode_fdinfowithpath
));
1247 fill_fileinfo(fp
, closeonexec
, &vfip
.pfi
);
1248 error
= fill_vnodeinfo(vp
, &vfip
.pvip
.vip_vi
) ;
1251 vn_getpath(vp
, &vfip
.pvip
.vip_path
[0], &count
);
1252 vfip
.pvip
.vip_path
[MAXPATHLEN
-1] = 0;
1254 error
= copyout((caddr_t
)&vfip
, buffer
, sizeof(struct vnode_fdinfowithpath
));
1256 *retval
= sizeof(struct vnode_fdinfowithpath
);
1263 fill_fileinfo(struct fileproc
* fp
, int closeonexec
, struct proc_fileinfo
* fproc
)
1265 fproc
->fi_openflags
= fp
->f_fglob
->fg_flag
;
1266 fproc
->fi_status
= 0;
1267 fproc
->fi_offset
= fp
->f_fglob
->fg_offset
;
1268 fproc
->fi_type
= fp
->f_fglob
->fg_type
;
1269 if (fp
->f_fglob
->fg_count
)
1270 fproc
->fi_status
|= PROC_FP_SHARED
;
1271 if (closeonexec
!= 0)
1272 fproc
->fi_status
|= PROC_FP_CLEXEC
;
1278 fill_vnodeinfo(vnode_t vp
, struct vnode_info
*vinfo
)
1280 vfs_context_t context
;
1284 context
= vfs_context_create((vfs_context_t
)0);
1285 error
= vn_stat(vp
, &sb
, NULL
, 1, context
);
1286 (void)vfs_context_rele(context
);
1288 munge_vinfo_stat(&sb
, &vinfo
->vi_stat
);
1293 if (vp
->v_mount
!= dead_mountp
) {
1294 vinfo
->vi_fsid
= vp
->v_mount
->mnt_vfsstat
.f_fsid
;
1296 vinfo
->vi_fsid
.val
[0] = 0;
1297 vinfo
->vi_fsid
.val
[1] = 0;
1299 vinfo
->vi_type
= vp
->v_type
;
1305 pid_socketinfo(socket_t so
, struct fileproc
*fp
, int closeonexec
, user_addr_t buffer
, __unused
uint32_t buffersize
, int32_t * retval
)
1308 struct socket_fdinfo s
;
1311 bzero(&s
, sizeof(struct socket_fdinfo
));
1312 fill_fileinfo(fp
, closeonexec
, &s
.pfi
);
1313 if ((error
= fill_socketinfo(so
, &s
.psi
)) == 0) {
1314 if ((error
= copyout(&s
, buffer
, sizeof(struct socket_fdinfo
))) == 0)
1315 *retval
= sizeof(struct socket_fdinfo
);
1325 pid_pseminfo(struct psemnode
*psem
, struct fileproc
*fp
, int closeonexec
, user_addr_t buffer
, __unused
uint32_t buffersize
, int32_t * retval
)
1327 struct psem_fdinfo pseminfo
;
1330 bzero(&pseminfo
, sizeof(struct psem_fdinfo
));
1331 fill_fileinfo(fp
, closeonexec
, &pseminfo
.pfi
);
1333 if ((error
= fill_pseminfo(psem
, &pseminfo
.pseminfo
)) == 0) {
1334 if ((error
= copyout(&pseminfo
, buffer
, sizeof(struct psem_fdinfo
))) == 0)
1335 *retval
= sizeof(struct psem_fdinfo
);
1342 pid_pshminfo(struct pshmnode
*pshm
, struct fileproc
*fp
, int closeonexec
, user_addr_t buffer
, __unused
uint32_t buffersize
, int32_t * retval
)
1344 struct pshm_fdinfo pshminfo
;
1347 bzero(&pshminfo
, sizeof(struct pshm_fdinfo
));
1348 fill_fileinfo(fp
, closeonexec
, &pshminfo
.pfi
);
1350 if ((error
= fill_pshminfo(pshm
, &pshminfo
.pshminfo
)) == 0) {
1351 if ((error
= copyout(&pshminfo
, buffer
, sizeof(struct pshm_fdinfo
))) == 0)
1352 *retval
= sizeof(struct pshm_fdinfo
);
1359 pid_pipeinfo(struct pipe
* p
, struct fileproc
*fp
, int closeonexec
, user_addr_t buffer
, __unused
uint32_t buffersize
, int32_t * retval
)
1361 struct pipe_fdinfo pipeinfo
;
1364 bzero(&pipeinfo
, sizeof(struct pipe_fdinfo
));
1365 fill_fileinfo(fp
, closeonexec
, &pipeinfo
.pfi
);
1366 if ((error
= fill_pipeinfo(p
, &pipeinfo
.pipeinfo
)) == 0) {
1367 if ((error
= copyout(&pipeinfo
, buffer
, sizeof(struct pipe_fdinfo
))) == 0)
1368 *retval
= sizeof(struct pipe_fdinfo
);
1375 pid_kqueueinfo(struct kqueue
* kq
, struct fileproc
*fp
, int closeonexec
, user_addr_t buffer
, __unused
uint32_t buffersize
, int32_t * retval
)
1377 struct kqueue_fdinfo kqinfo
;
1380 bzero(&kqinfo
, sizeof(struct kqueue_fdinfo
));
1382 fill_fileinfo(fp
, closeonexec
, &kqinfo
.pfi
);
1384 if ((error
= fill_kqueueinfo(kq
, &kqinfo
.kqueueinfo
)) == 0) {
1385 if ((error
= copyout(&kqinfo
, buffer
, sizeof(struct kqueue_fdinfo
))) == 0)
1386 *retval
= sizeof(struct kqueue_fdinfo
);
1393 pid_atalkinfo(__unused
struct atalk
* at
, __unused
struct fileproc
*fp
, __unused
int closeonexec
, __unused user_addr_t buffer
, __unused
uint32_t buffersize
, __unused
int32_t * retval
)
1400 /************************** proc_pidfdinfo routine ***************************/
1402 proc_pidfdinfo(int pid
, int flavor
, int fd
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
)
1405 int error
= ENOTSUP
;
1406 struct fileproc
* fp
;
1408 int closeonexec
= 0;
1411 case PROC_PIDFDVNODEINFO
:
1412 size
= PROC_PIDFDVNODEINFO_SIZE
;
1414 case PROC_PIDFDVNODEPATHINFO
:
1415 size
= PROC_PIDFDVNODEPATHINFO_SIZE
;
1417 case PROC_PIDFDSOCKETINFO
:
1418 size
= PROC_PIDFDSOCKETINFO_SIZE
;
1420 case PROC_PIDFDPSEMINFO
:
1421 size
= PROC_PIDFDPSEMINFO_SIZE
;
1423 case PROC_PIDFDPSHMINFO
:
1424 size
= PROC_PIDFDPSHMINFO_SIZE
;
1426 case PROC_PIDFDPIPEINFO
:
1427 size
= PROC_PIDFDPIPEINFO_SIZE
;
1429 case PROC_PIDFDKQUEUEINFO
:
1430 size
= PROC_PIDFDKQUEUEINFO_SIZE
;
1432 case PROC_PIDFDATALKINFO
:
1433 size
= PROC_PIDFDATALKINFO_SIZE
;
1441 if (buffersize
< size
)
1444 if ((p
= proc_find(pid
)) == PROC_NULL
) {
1448 /* Do we have permission to look into this ? */
1449 if ((error
= proc_security_policy(p
)) != 0) {
1454 case PROC_PIDFDVNODEINFO
: {
1458 if ((error
= fp_getfvpandvid(p
, fd
, &fp
, &vp
, &vid
)) !=0) {
1461 /* no need to be under the fdlock */
1462 closeonexec
= p
->p_fd
->fd_ofileflags
[fd
] & UF_EXCLOSE
;
1463 error
= pid_vnodeinfo(vp
, vid
, fp
, closeonexec
, buffer
, buffersize
, retval
);
1467 case PROC_PIDFDVNODEPATHINFO
: {
1471 if ((error
= fp_getfvpandvid(p
, fd
, &fp
, &vp
, &vid
)) !=0) {
1475 /* no need to be under the fdlock */
1476 closeonexec
= p
->p_fd
->fd_ofileflags
[fd
] & UF_EXCLOSE
;
1477 error
= pid_vnodeinfopath(vp
, vid
, fp
, closeonexec
, buffer
, buffersize
, retval
);
1481 case PROC_PIDFDSOCKETINFO
: {
1484 if ((error
= fp_getfsock(p
, fd
, &fp
, &so
)) !=0) {
1487 /* no need to be under the fdlock */
1488 closeonexec
= p
->p_fd
->fd_ofileflags
[fd
] & UF_EXCLOSE
;
1489 error
= pid_socketinfo(so
, fp
, closeonexec
, buffer
, buffersize
, retval
);
1493 case PROC_PIDFDPSEMINFO
: {
1494 struct psemnode
* psem
;
1496 if ((error
= fp_getfpsem(p
, fd
, &fp
, &psem
)) !=0) {
1499 /* no need to be under the fdlock */
1500 closeonexec
= p
->p_fd
->fd_ofileflags
[fd
] & UF_EXCLOSE
;
1501 error
= pid_pseminfo(psem
, fp
, closeonexec
, buffer
, buffersize
, retval
);
1505 case PROC_PIDFDPSHMINFO
: {
1506 struct pshmnode
* pshm
;
1508 if ((error
= fp_getfpshm(p
, fd
, &fp
, &pshm
)) !=0) {
1511 /* no need to be under the fdlock */
1512 closeonexec
= p
->p_fd
->fd_ofileflags
[fd
] & UF_EXCLOSE
;
1513 error
= pid_pshminfo(pshm
, fp
, closeonexec
, buffer
, buffersize
, retval
);
1517 case PROC_PIDFDPIPEINFO
: {
1518 struct pipe
* cpipe
;
1520 if ((error
= fp_getfpipe(p
, fd
, &fp
, &cpipe
)) !=0) {
1523 /* no need to be under the fdlock */
1524 closeonexec
= p
->p_fd
->fd_ofileflags
[fd
] & UF_EXCLOSE
;
1525 error
= pid_pipeinfo(cpipe
, fp
, closeonexec
, buffer
, buffersize
, retval
);
1529 case PROC_PIDFDKQUEUEINFO
: {
1532 if ((error
= fp_getfkq(p
, fd
, &fp
, &kq
)) !=0) {
1535 /* no need to be under the fdlock */
1536 closeonexec
= p
->p_fd
->fd_ofileflags
[fd
] & UF_EXCLOSE
;
1537 error
= pid_kqueueinfo(kq
, fp
, closeonexec
, buffer
, buffersize
, retval
);
1542 case PROC_PIDFDATALKINFO
: {
1545 if ((error
= fp_getfatalk(p
, fd
, &fp
, &at
)) !=0) {
1549 /* no need to be under the fdlock */
1550 closeonexec
= p
->p_fd
->fd_ofileflags
[fd
] & UF_EXCLOSE
;
1551 error
= pid_atalkinfo(at
, fp
, closeonexec
, buffer
, buffersize
, retval
);
1561 fp_drop(p
, fd
, fp
, 0);
1569 * Helper function for proc_pidfileportinfo
1572 struct fileport_info_args
{
1574 user_addr_t fia_buffer
;
1575 uint32_t fia_buffersize
;
1576 int32_t *fia_retval
;
1579 static kern_return_t
1580 proc_fileport_info(__unused mach_port_name_t name
,
1581 struct fileglob
*fg
, void *arg
)
1583 struct fileport_info_args
*fia
= arg
;
1584 struct fileproc __fileproc
, *fp
= &__fileproc
;
1587 bzero(fp
, sizeof (*fp
));
1590 switch (fia
->fia_flavor
) {
1591 case PROC_PIDFILEPORTVNODEPATHINFO
: {
1594 if (fg
->fg_type
!= DTYPE_VNODE
) {
1598 vp
= (struct vnode
*)fg
->fg_data
;
1599 error
= pid_vnodeinfopath(vp
, vnode_vid(vp
), fp
, 0,
1600 fia
->fia_buffer
, fia
->fia_buffersize
, fia
->fia_retval
);
1603 case PROC_PIDFILEPORTSOCKETINFO
: {
1606 if (fg
->fg_type
!= DTYPE_SOCKET
) {
1610 so
= (socket_t
)fg
->fg_data
;
1611 error
= pid_socketinfo(so
, fp
, 0,
1612 fia
->fia_buffer
, fia
->fia_buffersize
, fia
->fia_retval
);
1615 case PROC_PIDFILEPORTPSHMINFO
: {
1616 struct pshmnode
*pshm
;
1618 if (fg
->fg_type
!= DTYPE_PSXSHM
) {
1619 error
= EBADF
; /* ick - mirror fp_getfpshm */
1622 pshm
= (struct pshmnode
*)fg
->fg_data
;
1623 error
= pid_pshminfo(pshm
, fp
, 0,
1624 fia
->fia_buffer
, fia
->fia_buffersize
, fia
->fia_retval
);
1627 case PROC_PIDFILEPORTPIPEINFO
: {
1630 if (fg
->fg_type
!= DTYPE_PIPE
) {
1631 error
= EBADF
; /* ick - mirror fp_getfpipe */
1634 cpipe
= (struct pipe
*)fg
->fg_data
;
1635 error
= pid_pipeinfo(cpipe
, fp
, 0,
1636 fia
->fia_buffer
, fia
->fia_buffersize
, fia
->fia_retval
);
1647 /************************* proc_pidfileportinfo routine *********************/
1649 proc_pidfileportinfo(int pid
, int flavor
, mach_port_name_t name
,
1650 user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
)
1653 int error
= ENOTSUP
;
1655 struct fileport_info_args fia
;
1657 /* fileport types are restricted by filetype_issendable() */
1660 case PROC_PIDFILEPORTVNODEPATHINFO
:
1661 size
= PROC_PIDFILEPORTVNODEPATHINFO_SIZE
;
1663 case PROC_PIDFILEPORTSOCKETINFO
:
1664 size
= PROC_PIDFILEPORTSOCKETINFO_SIZE
;
1666 case PROC_PIDFILEPORTPSHMINFO
:
1667 size
= PROC_PIDFILEPORTPSHMINFO_SIZE
;
1669 case PROC_PIDFILEPORTPIPEINFO
:
1670 size
= PROC_PIDFILEPORTPIPEINFO_SIZE
;
1676 if (buffersize
< size
)
1678 if ((p
= proc_find(pid
)) == PROC_NULL
) {
1682 if ((error
= proc_security_policy(p
)) != 0) {
1686 fia
.fia_flavor
= flavor
;
1687 fia
.fia_buffer
= buffer
;
1688 fia
.fia_buffersize
= buffersize
;
1689 fia
.fia_retval
= retval
;
1691 if (fileport_invoke(p
->task
, name
,
1692 proc_fileport_info
, &fia
, &error
) != KERN_SUCCESS
)
1701 proc_security_policy(proc_t p
)
1703 kauth_cred_t my_cred
;
1706 my_cred
= kauth_cred_proc_ref(p
);
1707 uid
= kauth_cred_getuid(my_cred
) ;
1708 kauth_cred_unref(&my_cred
);
1710 if ((uid
!= kauth_cred_getuid(kauth_cred_get()))
1711 && suser(kauth_cred_get(), (u_short
*)0)) {
1719 proc_kernmsgbuf(user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
)
1721 if (suser(kauth_cred_get(), (u_short
*)0) == 0) {
1722 return(log_dmesg(buffer
, buffersize
, retval
));
1727 /* ********* process control sets on self only */
1729 proc_setcontrol(int pid
, int flavor
, uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, __unused
int32_t * retval
)
1731 struct proc
* pself
= PROC_NULL
;
1733 uint32_t pcontrol
= (uint32_t)arg
;
1734 struct uthread
*ut
= NULL
;
1737 pself
= current_proc();
1738 if (pid
!= pself
->p_pid
)
1743 case PROC_SELFSET_PCONTROL
: {
1744 if (pcontrol
> P_PCMAX
)
1747 /* reset existing control setting while retaining action state */
1748 pself
->p_pcaction
&= PROC_ACTION_MASK
;
1749 /* set new control state */
1750 pself
->p_pcaction
|= pcontrol
;
1755 case PROC_SELFSET_THREADNAME
: {
1756 /* PROC_SELFSET_THREADNAME_SIZE = (MAXTHREADNAMESIZE -1) */
1757 if(buffersize
> PROC_SELFSET_THREADNAME_SIZE
)
1758 return ENAMETOOLONG
;
1759 ut
= current_uthread();
1763 ut
->pth_name
= (char*)kalloc(MAXTHREADNAMESIZE
);
1767 bzero(ut
->pth_name
, MAXTHREADNAMESIZE
);
1768 error
= copyin(buffer
, ut
->pth_name
, buffersize
);
1772 case PROC_SELFSET_VMRSRCOWNER
: {
1773 /* need to to be superuser */
1774 if (suser(kauth_cred_get(), (u_short
*)0) != 0) {
1780 /* reset existing control setting while retaining action state */
1781 pself
->p_lflag
|= P_LVMRSRCOWNER
;
1786 case PROC_SELFSET_DELAYIDLESLEEP
: {
1787 /* mark or clear the process property to delay idle sleep disk IO */
1789 OSBitOrAtomic(P_DELAYIDLESLEEP
, &pself
->p_flag
);
1791 OSBitAndAtomic(~((uint32_t)P_DELAYIDLESLEEP
), &pself
->p_flag
);
1804 proc_dirty_start(struct proc
*p
)
1807 while (p
->p_dirty
& P_DIRTY_BUSY
) {
1808 msleep(&p
->p_dirty
, &p
->p_mlock
, 0, "proc_dirty_start", NULL
);
1810 p
->p_dirty
|= P_DIRTY_BUSY
;
1815 proc_dirty_end(struct proc
*p
)
1818 if (p
->p_dirty
& P_DIRTY_BUSY
) {
1819 p
->p_dirty
&= ~P_DIRTY_BUSY
;
1820 wakeup(&p
->p_dirty
);
1826 proc_validate_track_flags(uint32_t pcontrol
, struct proc
*target_p
) {
1827 /* Check idle exit isn't specified independently */
1828 if ((pcontrol
& PROC_DIRTY_TRACK_MASK
) == PROC_DIRTY_ALLOW_IDLE_EXIT
) {
1832 /* See that the process isn't marked for termination */
1833 if (target_p
->p_dirty
& P_DIRTY_TERMINATED
) {
1841 proc_dirtycontrol(int pid
, int flavor
, uint64_t arg
, int32_t *retval
) {
1842 struct proc
*target_p
;
1844 uint32_t pcontrol
= (uint32_t)arg
;
1845 kauth_cred_t my_cred
, target_cred
;
1846 boolean_t self
= FALSE
;
1847 boolean_t child
= FALSE
;
1850 target_p
= proc_find(pid
);
1851 if (target_p
== PROC_NULL
) {
1855 my_cred
= kauth_cred_get();
1856 target_cred
= kauth_cred_proc_ref(target_p
);
1858 selfpid
= proc_selfpid();
1859 if (pid
== selfpid
) {
1861 } else if (target_p
->p_ppid
== selfpid
) {
1866 case PROC_DIRTYCONTROL_TRACK
: {
1867 /* Only allow the process itself, its parent, or root */
1868 if ((self
== FALSE
) && (child
== FALSE
) && kauth_cred_issuser(kauth_cred_get()) != TRUE
) {
1873 proc_dirty_start(target_p
);
1875 if (proc_validate_track_flags(pcontrol
, target_p
)) {
1876 /* Cumulative, as per <rdar://problem/11159924> */
1877 target_p
->p_dirty
|=
1878 ((pcontrol
& PROC_DIRTY_TRACK
) ? P_DIRTY_TRACK
: 0) |
1879 ((pcontrol
& PROC_DIRTY_ALLOW_IDLE_EXIT
) ? P_DIRTY_ALLOW_IDLE_EXIT
: 0);
1880 #if CONFIG_MEMORYSTATUS
1881 if ((target_p
->p_dirty
& P_DIRTY_CAN_IDLE_EXIT
) == P_DIRTY_CAN_IDLE_EXIT
) {
1882 memorystatus_on_track_dirty(pid
, TRUE
);
1889 proc_dirty_end(target_p
);
1893 case PROC_DIRTYCONTROL_SET
: {
1894 boolean_t kill
= false;
1896 /* Check privileges; use cansignal() here since the process could be terminated */
1897 if (!cansignal(current_proc(), my_cred
, target_p
, SIGKILL
, 0)) {
1902 proc_dirty_start(target_p
);
1904 if (!(target_p
->p_dirty
& P_DIRTY_TRACK
)) {
1905 /* Dirty tracking not enabled */
1907 } else if (pcontrol
&& (target_p
->p_dirty
& P_DIRTY_TERMINATED
)) {
1909 * Process is set to be terminated and we're attempting to mark it dirty.
1910 * Set for termination and marking as clean is OK - see <rdar://problem/10594349>.
1914 int flag
= (self
== TRUE
) ? P_DIRTY
: P_DIRTY_SHUTDOWN
;
1915 if (pcontrol
&& !(target_p
->p_dirty
& flag
)) {
1916 target_p
->p_dirty
|= flag
;
1917 } else if ((pcontrol
== 0) && (target_p
->p_dirty
& flag
)) {
1918 if ((flag
== P_DIRTY_SHUTDOWN
) && (!target_p
->p_dirty
& P_DIRTY
)) {
1919 /* Clearing the dirty shutdown flag, and the process is otherwise clean - kill */
1920 target_p
->p_dirty
|= P_DIRTY_TERMINATED
;
1922 } else if ((flag
== P_DIRTY
) && (target_p
->p_dirty
& P_DIRTY_TERMINATED
)) {
1923 /* Kill previously terminated processes if set clean */
1926 target_p
->p_dirty
&= ~flag
;
1932 #if CONFIG_MEMORYSTATUS
1933 if ((error
== 0) && ((target_p
->p_dirty
& P_DIRTY_CAN_IDLE_EXIT
) == P_DIRTY_CAN_IDLE_EXIT
)) {
1934 memorystatus_on_dirty(pid
, pcontrol
? TRUE
: FALSE
);
1937 proc_dirty_end(target_p
);
1939 if ((error
== 0) && (kill
== true)) {
1940 psignal(target_p
, SIGKILL
);
1945 case PROC_DIRTYCONTROL_GET
: {
1946 /* No permissions check - dirty state is freely available */
1948 proc_dirty_start(target_p
);
1951 if (target_p
->p_dirty
& P_DIRTY_TRACK
) {
1952 *retval
|= PROC_DIRTY_TRACKED
;
1953 if (target_p
->p_dirty
& P_DIRTY_ALLOW_IDLE_EXIT
) {
1954 *retval
|= PROC_DIRTY_ALLOWS_IDLE_EXIT
;
1956 if (target_p
->p_dirty
& P_DIRTY
) {
1957 *retval
|= PROC_DIRTY_IS_DIRTY
;
1961 proc_dirty_end(target_p
);
1970 proc_rele(target_p
);
1971 kauth_cred_unref(&target_cred
);
1977 * proc_terminate() provides support for sudden termination.
1978 * SIGKILL is issued to tracked, clean processes; otherwise,
1983 proc_terminate(int pid
, int32_t *retval
)
1987 kauth_cred_t uc
= kauth_cred_get();
1991 /* XXX: Check if these are necessary */
1992 AUDIT_ARG(pid
, pid
);
1993 AUDIT_ARG(signum
, sig
);
1996 if (pid
<= 0 || retval
== NULL
) {
2000 if ((p
= proc_find(pid
)) == NULL
) {
2005 /* XXX: Check if these are necessary */
2006 AUDIT_ARG(process
, p
);
2009 /* Check privileges; if SIGKILL can be issued, then SIGTERM is also OK */
2010 if (!cansignal(current_proc(), uc
, p
, SIGKILL
, 0)) {
2015 proc_dirty_start(p
);
2017 p
->p_dirty
|= P_DIRTY_TERMINATED
;
2019 if ((p
->p_dirty
& (P_DIRTY_TRACK
|P_DIRTY_IS_DIRTY
)) == P_DIRTY_TRACK
) {
2020 /* Clean; mark as terminated and issue SIGKILL */
2023 /* Dirty, terminated, or state tracking is unsupported; issue SIGTERM to allow cleanup */
2029 proc_removethrottle(p
);
2041 proc_removethrottle(proc_t p
)
2044 /* remove throttled states in all threads; process is going to terminate soon */
2047 /* if already marked marked for proc_termiantion.. */
2048 if ((p
->p_lflag
& P_LPTERMINATE
) != 0) {
2052 p
->p_lflag
|= P_LPTERMINATE
;
2055 (void)proc_task_remove_throttle(p
->task
);
2061 * copy stat64 structure into vinfo_stat structure.
2064 munge_vinfo_stat(struct stat64
*sbp
, struct vinfo_stat
*vsbp
)
2066 bzero(vsbp
, sizeof(struct vinfo_stat
));
2068 vsbp
->vst_dev
= sbp
->st_dev
;
2069 vsbp
->vst_mode
= sbp
->st_mode
;
2070 vsbp
->vst_nlink
= sbp
->st_nlink
;
2071 vsbp
->vst_ino
= sbp
->st_ino
;
2072 vsbp
->vst_uid
= sbp
->st_uid
;
2073 vsbp
->vst_gid
= sbp
->st_gid
;
2074 vsbp
->vst_atime
= sbp
->st_atimespec
.tv_sec
;
2075 vsbp
->vst_atimensec
= sbp
->st_atimespec
.tv_nsec
;
2076 vsbp
->vst_mtime
= sbp
->st_mtimespec
.tv_sec
;
2077 vsbp
->vst_mtimensec
= sbp
->st_mtimespec
.tv_nsec
;
2078 vsbp
->vst_ctime
= sbp
->st_ctimespec
.tv_sec
;
2079 vsbp
->vst_ctimensec
= sbp
->st_ctimespec
.tv_nsec
;
2080 vsbp
->vst_birthtime
= sbp
->st_birthtimespec
.tv_sec
;
2081 vsbp
->vst_birthtimensec
= sbp
->st_birthtimespec
.tv_nsec
;
2082 vsbp
->vst_size
= sbp
->st_size
;
2083 vsbp
->vst_blocks
= sbp
->st_blocks
;
2084 vsbp
->vst_blksize
= sbp
->st_blksize
;
2085 vsbp
->vst_flags
= sbp
->st_flags
;
2086 vsbp
->vst_gen
= sbp
->st_gen
;
2087 vsbp
->vst_rdev
= sbp
->st_rdev
;
2088 vsbp
->vst_qspare
[0] = sbp
->st_qspare
[0];
2089 vsbp
->vst_qspare
[1] = sbp
->st_qspare
[1];