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>
52 #include <security/audit/audit.h>
54 #include <mach/machine.h>
55 #include <mach/mach_types.h>
56 #include <mach/vm_param.h>
57 #include <kern/task.h>
58 #include <kern/lock.h>
59 #include <kern/kalloc.h>
60 #include <kern/assert.h>
61 #include <vm/vm_kern.h>
62 #include <vm/vm_map.h>
63 #include <mach/host_info.h>
64 #include <mach/task_info.h>
65 #include <mach/thread_info.h>
66 #include <mach/vm_region.h>
68 #include <sys/mount_internal.h>
69 #include <sys/proc_info.h>
70 #include <sys/bsdtask_info.h>
71 #include <sys/kdebug.h>
72 #include <sys/sysproto.h>
73 #include <sys/msgbuf.h>
75 #include <sys/msgbuf.h>
77 #include <machine/machine_routines.h>
79 #include <kern/ipc_misc.h>
81 #include <vm/vm_protos.h>
89 uint64_t get_dispatchqueue_offset_from_proc(void *);
90 int proc_info_internal(int callnum
, int pid
, int flavor
, uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
);
92 /* protos for proc_info calls */
93 int proc_listpids(uint32_t type
, uint32_t tyoneinfo
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
);
94 int proc_pidinfo(int pid
, int flavor
, uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
);
95 int proc_pidfdinfo(int pid
, int flavor
,int fd
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
);
96 int proc_kernmsgbuf(user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
);
97 int proc_setcontrol(int pid
, int flavor
, uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
);
98 int proc_pidfileportinfo(int pid
, int flavor
, mach_port_name_t name
, user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
);
100 /* protos for procpidinfo calls */
101 int proc_pidfdlist(proc_t p
, user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
);
102 int proc_pidbsdinfo(proc_t p
, struct proc_bsdinfo
*pbsd
, int zombie
);
103 int proc_pidshortbsdinfo(proc_t p
, struct proc_bsdshortinfo
*pbsd_shortp
, int zombie
);
104 int proc_pidtaskinfo(proc_t p
, struct proc_taskinfo
*ptinfo
);
105 int proc_pidallinfo(proc_t p
, int flavor
, uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
);
106 int proc_pidthreadinfo(proc_t p
, uint64_t arg
, struct proc_threadinfo
*pthinfo
);
107 int proc_pidthreadpathinfo(proc_t p
, uint64_t arg
, struct proc_threadwithpathinfo
*pinfo
);
108 int proc_pidlistthreads(proc_t p
, user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
);
109 int proc_pidregioninfo(proc_t p
, uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
);
110 int proc_pidregionpathinfo(proc_t p
, uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
);
111 int proc_pidvnodepathinfo(proc_t p
, uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
);
112 int proc_pidpathinfo(proc_t p
, uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
);
113 int proc_pidworkqueueinfo(proc_t p
, struct proc_workqueueinfo
*pwqinfo
);
114 int proc_pidfileportlist(proc_t p
, user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
);
117 /* protos for proc_pidfdinfo calls */
118 int pid_vnodeinfo(vnode_t vp
, uint32_t vid
, struct fileproc
* fp
, int closeonexec
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
);
119 int pid_vnodeinfopath(vnode_t vp
, uint32_t vid
, struct fileproc
* fp
, int closeonexec
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
);
120 int pid_socketinfo(socket_t so
, struct fileproc
*fp
, int closeonexec
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
);
121 int pid_pseminfo(struct psemnode
* psem
, struct fileproc
* fp
, int closeonexec
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
);
122 int pid_pshminfo(struct pshmnode
* pshm
, struct fileproc
* fp
, int closeonexec
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
);
123 int pid_pipeinfo(struct pipe
* p
, struct fileproc
* fp
, int closeonexec
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
);
124 int pid_kqueueinfo(struct kqueue
* kq
, struct fileproc
* fp
, int closeonexec
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
);
125 int pid_atalkinfo(struct atalk
* at
, struct fileproc
* fp
, int closeonexec
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
);
128 /* protos for misc */
130 int fill_vnodeinfo(vnode_t vp
, struct vnode_info
*vinfo
);
131 void fill_fileinfo(struct fileproc
* fp
, int closeonexec
, struct proc_fileinfo
* finfo
);
132 static int proc_security_policy(proc_t p
);
133 static void munge_vinfo_stat(struct stat64
*sbp
, struct vinfo_stat
*vsbp
);
135 uint64_t get_dispatchqueue_offset_from_proc(void *p
)
138 proc_t pself
= (proc_t
)p
;
139 return (pself
->p_dispatchqueue_offset
);
145 /***************************** proc_info ********************/
148 proc_info(__unused
struct proc
*p
, struct proc_info_args
* uap
, int32_t *retval
)
150 return(proc_info_internal(uap
->callnum
, uap
->pid
, uap
->flavor
, uap
->arg
, uap
->buffer
, uap
->buffersize
, retval
));
155 proc_info_internal(int callnum
, int pid
, int flavor
, uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
)
159 case 1: /* proc_listpids */
160 /* pid contains type and flavor contains typeinfo */
161 return(proc_listpids(pid
, flavor
, buffer
, buffersize
, retval
));
162 case 2: /* proc_pidinfo */
163 return(proc_pidinfo(pid
, flavor
, arg
, buffer
, buffersize
, retval
));
164 case 3: /* proc_pidfdinfo */
165 return(proc_pidfdinfo(pid
, flavor
, (int)arg
, buffer
, buffersize
, retval
));
166 case 4: /* proc_kernmsgbuf */
167 return(proc_kernmsgbuf(buffer
, buffersize
, retval
));
168 case 5: /* set on self properties proc_setcontrol */
169 return(proc_setcontrol(pid
, flavor
, arg
, buffer
, buffersize
, retval
));
170 case 6: /* proc_pidfileportinfo */
171 return(proc_pidfileportinfo(pid
, flavor
, (mach_port_name_t
)arg
, buffer
, buffersize
, retval
));
180 /******************* proc_listpids routine ****************/
182 proc_listpids(uint32_t type
, uint32_t typeinfo
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
)
184 int numprocs
, wantpids
;
191 struct proclist
*current_list
;
193 /* if the buffer is null, return num of procs */
194 if (buffer
== (user_addr_t
)0) {
195 *retval
= ((nprocs
+20) * sizeof(int));
199 if (buffersize
< sizeof(int)) {
202 wantpids
= buffersize
/sizeof(int);
203 numprocs
= nprocs
+20;
204 if (numprocs
> wantpids
)
207 kbuf
= (char *)kalloc((vm_size_t
)(numprocs
* sizeof(int)));
210 bzero(kbuf
, sizeof(int));
217 current_list
= &allproc
;
219 LIST_FOREACH(p
, current_list
, p_list
) {
223 if (p
->p_pgrpid
!= (pid_t
)typeinfo
)
227 if ((p
->p_ppid
!= (pid_t
)typeinfo
) && (((p
->p_lflag
& P_LTRACED
) == 0) || (p
->p_oppid
!= (pid_t
)typeinfo
)))
235 /* racy but list lock is held */
236 if ((p
->p_flag
& P_CONTROLT
) == 0 ||
237 (p
->p_pgrp
== NULL
) || (p
->p_pgrp
->pg_session
== NULL
) ||
238 (tp
= SESSION_TP(p
->p_pgrp
->pg_session
)) == TTY_NULL
||
239 tp
->t_dev
!= (dev_t
)typeinfo
)
243 if (p
->p_ucred
== NULL
)
246 kauth_cred_t my_cred
;
249 my_cred
= kauth_cred_proc_ref(p
);
250 uid
= kauth_cred_getuid(my_cred
);
251 kauth_cred_unref(&my_cred
);
252 if (uid
!= (uid_t
)typeinfo
)
257 if (p
->p_ucred
== NULL
)
260 kauth_cred_t my_cred
;
263 my_cred
= kauth_cred_proc_ref(p
);
264 uid
= kauth_cred_getruid(my_cred
);
265 kauth_cred_unref(&my_cred
);
266 if (uid
!= (uid_t
)typeinfo
)
283 if ((n
< numprocs
) && (current_list
== &allproc
)) {
284 current_list
= &zombproc
;
291 error
= copyout((caddr_t
)ptr
, buffer
, n
* sizeof(int));
293 *retval
= (n
* sizeof(int));
294 kfree((void *)kbuf
, (vm_size_t
)(numprocs
* sizeof(int)));
300 /********************************** proc_pidinfo routines ********************************/
303 proc_pidfdlist(proc_t p
, user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
)
307 struct proc_fdinfo
* pfd
;
308 struct fileproc
* fp
;
313 numfds
= p
->p_fd
->fd_nfiles
;
315 if (buffer
== (user_addr_t
) 0) {
317 *retval
= (numfds
* sizeof(struct proc_fdinfo
));
321 /* buffersize is big enough atleast for one struct */
322 needfds
= buffersize
/sizeof(struct proc_fdinfo
);
324 if (numfds
> needfds
)
327 kbuf
= (char *)kalloc((vm_size_t
)(numfds
* sizeof(struct proc_fdinfo
)));
330 bzero(kbuf
, numfds
* sizeof(struct proc_fdinfo
));
334 pfd
= (struct proc_fdinfo
*)kbuf
;
336 for (n
= 0; ((n
< numfds
) && (n
< p
->p_fd
->fd_nfiles
)); n
++) {
337 if (((fp
= p
->p_fd
->fd_ofiles
[n
]) != 0)
338 && ((p
->p_fd
->fd_ofileflags
[n
] & UF_RESERVED
) == 0)) {
340 pfd
->proc_fdtype
= fp
->f_fglob
->fg_type
;
347 error
= copyout(kbuf
, buffer
, count
* sizeof(struct proc_fdinfo
));
348 kfree((void *)kbuf
, (vm_size_t
)(numfds
* sizeof(struct proc_fdinfo
)));
350 *retval
= (count
* sizeof(struct proc_fdinfo
));
355 * Helper functions for proc_pidfileportlist.
358 proc_fileport_count(__unused mach_port_name_t name
,
359 __unused
struct fileglob
*fg
, void *arg
)
361 uint32_t *counter
= arg
;
367 struct fileport_fdtype_args
{
368 struct proc_fileportinfo
*ffa_pfi
;
369 struct proc_fileportinfo
*ffa_pfi_end
;
373 proc_fileport_fdtype(mach_port_name_t name
, struct fileglob
*fg
, void *arg
)
375 struct fileport_fdtype_args
*ffa
= arg
;
377 if (ffa
->ffa_pfi
!= ffa
->ffa_pfi_end
) {
378 ffa
->ffa_pfi
->proc_fdtype
= fg
->fg_type
;
379 ffa
->ffa_pfi
->proc_fileport
= name
;
381 return (0); /* keep walking */
383 return (-1); /* stop the walk! */
387 proc_pidfileportlist(proc_t p
,
388 user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
)
392 struct proc_fileportinfo
*pfi
;
393 uint32_t needfileports
, numfileports
;
394 struct fileport_fdtype_args ffa
;
397 needfileports
= buffersize
/ sizeof (*pfi
);
398 if ((user_addr_t
)0 == buffer
|| needfileports
> (uint32_t)maxfiles
) {
400 * Either (i) the user is asking for a fileport count,
401 * or (ii) the number of fileports they're asking for is
402 * larger than the maximum number of open files (!); count
403 * them to bound subsequent heap allocations.
406 switch (fileport_walk(p
->task
,
407 proc_fileport_count
, &numfileports
)) {
410 case KERN_RESOURCE_SHORTAGE
:
412 case KERN_INVALID_TASK
:
418 if (numfileports
== 0) {
419 *retval
= 0; /* none at all, bail */
422 if ((user_addr_t
)0 == buffer
) {
423 numfileports
+= 20; /* accelerate convergence */
424 *retval
= numfileports
* sizeof (*pfi
);
427 if (needfileports
> numfileports
)
428 needfileports
= numfileports
;
431 assert(buffersize
>= PROC_PIDLISTFILEPORTS_SIZE
);
433 kbufsize
= (vm_size_t
)needfileports
* sizeof (*pfi
);
434 pfi
= kbuf
= kalloc(kbufsize
);
437 bzero(kbuf
, kbufsize
);
440 ffa
.ffa_pfi_end
= pfi
+ needfileports
;
442 switch (fileport_walk(p
->task
, proc_fileport_fdtype
, &ffa
)) {
446 if ((numfileports
= pfi
- (typeof(pfi
))kbuf
) == 0)
448 if (numfileports
> needfileports
)
449 panic("more fileports returned than requested");
450 error
= copyout(kbuf
, buffer
, numfileports
* sizeof (*pfi
));
452 case KERN_RESOURCE_SHORTAGE
:
455 case KERN_INVALID_TASK
:
462 kfree(kbuf
, kbufsize
);
464 *retval
= numfileports
* sizeof (*pfi
);
469 proc_pidbsdinfo(proc_t p
, struct proc_bsdinfo
* pbsd
, int zombie
)
471 register struct tty
*tp
;
472 struct session
*sessionp
= NULL
;
474 kauth_cred_t my_cred
;
477 sessionp
= proc_session(p
);
479 my_cred
= kauth_cred_proc_ref(p
);
480 bzero(pbsd
, sizeof(struct proc_bsdinfo
));
481 pbsd
->pbi_status
= p
->p_stat
;
482 pbsd
->pbi_xstatus
= p
->p_xstat
;
483 pbsd
->pbi_pid
= p
->p_pid
;
484 pbsd
->pbi_ppid
= p
->p_ppid
;
485 pbsd
->pbi_uid
= kauth_cred_getuid(my_cred
);
486 pbsd
->pbi_gid
= kauth_cred_getgid(my_cred
);
487 pbsd
->pbi_ruid
= kauth_cred_getruid(my_cred
);
488 pbsd
->pbi_rgid
= kauth_cred_getrgid(my_cred
);
489 pbsd
->pbi_svuid
= kauth_cred_getsvuid(my_cred
);
490 pbsd
->pbi_svgid
= kauth_cred_getsvgid(my_cred
);
491 kauth_cred_unref(&my_cred
);
493 pbsd
->pbi_nice
= p
->p_nice
;
494 pbsd
->pbi_start_tvsec
= p
->p_start
.tv_sec
;
495 pbsd
->pbi_start_tvusec
= p
->p_start
.tv_usec
;
496 bcopy(&p
->p_comm
, &pbsd
->pbi_comm
[0], MAXCOMLEN
);
497 pbsd
->pbi_comm
[MAXCOMLEN
- 1] = '\0';
498 bcopy(&p
->p_name
, &pbsd
->pbi_name
[0], 2*MAXCOMLEN
);
499 pbsd
->pbi_name
[(2*MAXCOMLEN
) - 1] = '\0';
502 if ((p
->p_flag
& P_SYSTEM
) == P_SYSTEM
)
503 pbsd
->pbi_flags
|= PROC_FLAG_SYSTEM
;
504 if ((p
->p_lflag
& P_LTRACED
) == P_LTRACED
)
505 pbsd
->pbi_flags
|= PROC_FLAG_TRACED
;
506 if ((p
->p_lflag
& P_LEXIT
) == P_LEXIT
)
507 pbsd
->pbi_flags
|= PROC_FLAG_INEXIT
;
508 if ((p
->p_lflag
& P_LPPWAIT
) == P_LPPWAIT
)
509 pbsd
->pbi_flags
|= PROC_FLAG_PPWAIT
;
510 if ((p
->p_flag
& P_LP64
) == P_LP64
)
511 pbsd
->pbi_flags
|= PROC_FLAG_LP64
;
512 if ((p
->p_flag
& P_CONTROLT
) == P_CONTROLT
)
513 pbsd
->pbi_flags
|= PROC_FLAG_CONTROLT
;
514 if ((p
->p_flag
& P_THCWD
) == P_THCWD
)
515 pbsd
->pbi_flags
|= PROC_FLAG_THCWD
;
516 if ((p
->p_flag
& P_SUGID
) == P_SUGID
)
517 pbsd
->pbi_flags
|= PROC_FLAG_PSUGID
;
518 if ((p
->p_flag
& P_EXEC
) == P_EXEC
)
519 pbsd
->pbi_flags
|= PROC_FLAG_EXEC
;
521 if (sessionp
!= SESSION_NULL
) {
522 if (SESS_LEADER(p
, sessionp
))
523 pbsd
->pbi_flags
|= PROC_FLAG_SLEADER
;
524 if (sessionp
->s_ttyvp
)
525 pbsd
->pbi_flags
|= PROC_FLAG_CTTY
;
529 switch(PROC_CONTROL_STATE(p
)) {
531 pbsd
->pbi_flags
|= PROC_FLAG_PC_THROTTLE
;
534 pbsd
->pbi_flags
|= PROC_FLAG_PC_SUSP
;
537 pbsd
->pbi_flags
|= PROC_FLAG_PC_KILL
;
541 switch(PROC_ACTION_STATE(p
)) {
543 pbsd
->pbi_flags
|= PROC_FLAG_PA_THROTTLE
;
546 pbsd
->pbi_flags
|= PROC_FLAG_PA_SUSP
;
550 /* if process is a zombie skip bg state */
551 if ((zombie
== 0) && (p
->p_stat
!= SZOMB
) && (p
->task
!= TASK_NULL
))
552 proc_get_darwinbgstate(p
->task
, &pbsd
->pbi_flags
);
555 pbsd
->pbi_nfiles
= p
->p_fd
->fd_nfiles
;
556 if (pg
!= PGRP_NULL
) {
557 pbsd
->pbi_pgid
= p
->p_pgrpid
;
558 pbsd
->pbi_pjobc
= pg
->pg_jobc
;
559 if ((p
->p_flag
& P_CONTROLT
) && (sessionp
!= SESSION_NULL
) && (tp
= SESSION_TP(sessionp
))) {
560 pbsd
->e_tdev
= tp
->t_dev
;
561 pbsd
->e_tpgid
= sessionp
->s_ttypgrpid
;
564 if (sessionp
!= SESSION_NULL
)
565 session_rele(sessionp
);
574 proc_pidshortbsdinfo(proc_t p
, struct proc_bsdshortinfo
* pbsd_shortp
, int zombie
)
576 bzero(pbsd_shortp
, sizeof(struct proc_bsdshortinfo
));
577 pbsd_shortp
->pbsi_pid
= p
->p_pid
;
578 pbsd_shortp
->pbsi_ppid
= p
->p_ppid
;
579 pbsd_shortp
->pbsi_pgid
= p
->p_pgrpid
;
580 pbsd_shortp
->pbsi_status
= p
->p_stat
;
581 bcopy(&p
->p_comm
, &pbsd_shortp
->pbsi_comm
[0], MAXCOMLEN
);
582 pbsd_shortp
->pbsi_comm
[MAXCOMLEN
- 1] = '\0';
584 pbsd_shortp
->pbsi_flags
= 0;
585 if ((p
->p_flag
& P_SYSTEM
) == P_SYSTEM
)
586 pbsd_shortp
->pbsi_flags
|= PROC_FLAG_SYSTEM
;
587 if ((p
->p_lflag
& P_LTRACED
) == P_LTRACED
)
588 pbsd_shortp
->pbsi_flags
|= PROC_FLAG_TRACED
;
589 if ((p
->p_lflag
& P_LEXIT
) == P_LEXIT
)
590 pbsd_shortp
->pbsi_flags
|= PROC_FLAG_INEXIT
;
591 if ((p
->p_lflag
& P_LPPWAIT
) == P_LPPWAIT
)
592 pbsd_shortp
->pbsi_flags
|= PROC_FLAG_PPWAIT
;
593 if ((p
->p_flag
& P_LP64
) == P_LP64
)
594 pbsd_shortp
->pbsi_flags
|= PROC_FLAG_LP64
;
595 if ((p
->p_flag
& P_CONTROLT
) == P_CONTROLT
)
596 pbsd_shortp
->pbsi_flags
|= PROC_FLAG_CONTROLT
;
597 if ((p
->p_flag
& P_THCWD
) == P_THCWD
)
598 pbsd_shortp
->pbsi_flags
|= PROC_FLAG_THCWD
;
599 if ((p
->p_flag
& P_SUGID
) == P_SUGID
)
600 pbsd_shortp
->pbsi_flags
|= PROC_FLAG_PSUGID
;
601 if ((p
->p_flag
& P_EXEC
) == P_EXEC
)
602 pbsd_shortp
->pbsi_flags
|= PROC_FLAG_EXEC
;
604 switch(PROC_CONTROL_STATE(p
)) {
606 pbsd_shortp
->pbsi_flags
|= PROC_FLAG_PC_THROTTLE
;
609 pbsd_shortp
->pbsi_flags
|= PROC_FLAG_PC_SUSP
;
612 pbsd_shortp
->pbsi_flags
|= PROC_FLAG_PC_KILL
;
616 switch(PROC_ACTION_STATE(p
)) {
618 pbsd_shortp
->pbsi_flags
|= PROC_FLAG_PA_THROTTLE
;
621 pbsd_shortp
->pbsi_flags
|= PROC_FLAG_PA_SUSP
;
625 /* if process is a zombie skip bg state */
626 if ((zombie
== 0) && (p
->p_stat
!= SZOMB
) && (p
->task
!= TASK_NULL
))
627 proc_get_darwinbgstate(p
->task
, &pbsd_shortp
->pbsi_flags
);
629 pbsd_shortp
->pbsi_uid
= p
->p_uid
;
630 pbsd_shortp
->pbsi_gid
= p
->p_gid
;
631 pbsd_shortp
->pbsi_ruid
= p
->p_ruid
;
632 pbsd_shortp
->pbsi_rgid
= p
->p_rgid
;
633 pbsd_shortp
->pbsi_svuid
= p
->p_svuid
;
634 pbsd_shortp
->pbsi_svgid
= p
->p_svgid
;
640 proc_pidtaskinfo(proc_t p
, struct proc_taskinfo
* ptinfo
)
646 bzero(ptinfo
, sizeof(struct proc_taskinfo
));
647 fill_taskprocinfo(task
, (struct proc_taskinfo_internal
*)ptinfo
);
655 proc_pidthreadinfo(proc_t p
, uint64_t arg
, struct proc_threadinfo
*pthinfo
)
658 uint64_t threadaddr
= (uint64_t)arg
;
660 bzero(pthinfo
, sizeof(struct proc_threadinfo
));
662 error
= fill_taskthreadinfo(p
->task
, threadaddr
, (struct proc_threadinfo_internal
*)pthinfo
, NULL
, NULL
);
671 bsd_getthreadname(void *uth
, char *buffer
)
673 struct uthread
*ut
= (struct uthread
*)uth
;
675 bcopy(ut
->pth_name
,buffer
,MAXTHREADNAMESIZE
);
679 bsd_threadcdir(void * uth
, void *vptr
, int *vidp
)
681 struct uthread
* ut
= (struct uthread
*)uth
;
683 vnode_t
*vpp
= (vnode_t
*)vptr
;
697 proc_pidthreadpathinfo(proc_t p
, uint64_t arg
, struct proc_threadwithpathinfo
*pinfo
)
702 uint64_t threadaddr
= (uint64_t)arg
;
705 bzero(pinfo
, sizeof(struct proc_threadwithpathinfo
));
707 error
= fill_taskthreadinfo(p
->task
, threadaddr
, (struct proc_threadinfo_internal
*)&pinfo
->pt
, (void *)&vp
, &vid
);
711 if ((vp
!= NULLVP
) && ((vnode_getwithvid(vp
, vid
)) == 0)) {
712 error
= fill_vnodeinfo(vp
, &pinfo
->pvip
.vip_vi
) ;
715 vn_getpath(vp
, &pinfo
->pvip
.vip_path
[0], &count
);
716 pinfo
->pvip
.vip_path
[MAXPATHLEN
-1] = 0;
726 proc_pidlistthreads(proc_t p
, user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
)
735 count
= buffersize
/(sizeof(uint64_t));
736 numthreads
= get_numthreads(p
->task
);
740 if (numthreads
> count
)
743 kbuf
= (void *)kalloc(numthreads
* sizeof(uint64_t));
746 bzero(kbuf
, numthreads
* sizeof(uint64_t));
748 ret
= fill_taskthreadlist(p
->task
, kbuf
, numthreads
);
750 error
= copyout(kbuf
, buffer
, ret
);
751 kfree(kbuf
, numthreads
* sizeof(uint64_t));
760 proc_pidregioninfo(proc_t p
, uint64_t arg
, user_addr_t buffer
, __unused
uint32_t buffersize
, int32_t *retval
)
762 struct proc_regioninfo preginfo
;
765 bzero(&preginfo
, sizeof(struct proc_regioninfo
));
766 ret
= fill_procregioninfo( p
->task
, arg
, (struct proc_regioninfo_internal
*)&preginfo
, (uintptr_t *)0, (uint32_t *)0);
769 error
= copyout(&preginfo
, buffer
, sizeof(struct proc_regioninfo
));
771 *retval
= sizeof(struct proc_regioninfo
);
777 proc_pidregionpathinfo(proc_t p
, uint64_t arg
, user_addr_t buffer
, __unused
uint32_t buffersize
, int32_t *retval
)
779 struct proc_regionwithpathinfo preginfo
;
781 uintptr_t vnodeaddr
= 0;
786 bzero(&preginfo
, sizeof(struct proc_regionwithpathinfo
));
788 ret
= fill_procregioninfo( p
->task
, arg
, (struct proc_regioninfo_internal
*)&preginfo
.prp_prinfo
, (uintptr_t *)&vnodeaddr
, (uint32_t *)&vnodeid
);
792 vp
= (vnode_t
)vnodeaddr
;
793 if ((vnode_getwithvid(vp
, vnodeid
)) == 0) {
794 /* FILL THE VNODEINFO */
795 error
= fill_vnodeinfo(vp
, &preginfo
.prp_vip
.vip_vi
);
797 vn_getpath(vp
, &preginfo
.prp_vip
.vip_path
[0], &count
);
798 /* Always make sure it is null terminated */
799 preginfo
.prp_vip
.vip_path
[MAXPATHLEN
-1] = 0;
803 error
= copyout(&preginfo
, buffer
, sizeof(struct proc_regionwithpathinfo
));
805 *retval
= sizeof(struct proc_regionwithpathinfo
);
810 * Path is relative to current process directory; may different from current
814 proc_pidvnodepathinfo(proc_t p
, __unused
uint64_t arg
, user_addr_t buffer
, __unused
uint32_t buffersize
, int32_t *retval
)
816 struct proc_vnodepathinfo pvninfo
;
818 vnode_t vncdirvp
= NULLVP
;
820 vnode_t vnrdirvp
= NULLVP
;
824 bzero(&pvninfo
, sizeof(struct proc_vnodepathinfo
));
827 if (p
->p_fd
->fd_cdir
) {
828 vncdirvp
= p
->p_fd
->fd_cdir
;
829 vncdirid
= p
->p_fd
->fd_cdir
->v_id
;
831 if (p
->p_fd
->fd_rdir
) {
832 vnrdirvp
= p
->p_fd
->fd_rdir
;
833 vnrdirid
= p
->p_fd
->fd_rdir
->v_id
;
837 if (vncdirvp
!= NULLVP
) {
838 if ((error
= vnode_getwithvid(vncdirvp
, vncdirid
)) == 0) {
839 /* FILL THE VNODEINFO */
840 error
= fill_vnodeinfo(vncdirvp
, &pvninfo
.pvi_cdir
.vip_vi
);
843 vn_getpath(vncdirvp
, &pvninfo
.pvi_cdir
.vip_path
[0], &count
);
844 pvninfo
.pvi_cdir
.vip_path
[MAXPATHLEN
-1] = 0;
852 if ((error
== 0) && (vnrdirvp
!= NULLVP
)) {
853 if ((error
= vnode_getwithvid(vnrdirvp
, vnrdirid
)) == 0) {
854 /* FILL THE VNODEINFO */
855 error
= fill_vnodeinfo(vnrdirvp
, &pvninfo
.pvi_rdir
.vip_vi
);
858 vn_getpath(vnrdirvp
, &pvninfo
.pvi_rdir
.vip_path
[0], &count
);
859 pvninfo
.pvi_rdir
.vip_path
[MAXPATHLEN
-1] = 0;
867 error
= copyout(&pvninfo
, buffer
, sizeof(struct proc_vnodepathinfo
));
869 *retval
= sizeof(struct proc_vnodepathinfo
);
876 proc_pidpathinfo(proc_t p
, __unused
uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, __unused
int32_t *retval
)
880 vnode_t nvp
= NULLVP
;
881 int len
= buffersize
;
889 buf
= (char *)kalloc(buffersize
);
894 vid
= vnode_vid(tvp
);
895 error
= vnode_getwithvid(tvp
, vid
);
897 error
= vn_getpath_fsenter(tvp
, buf
, &len
);
900 error
= vnode_lookup(buf
, 0, &nvp
, vfs_context_current());
901 if ((error
== 0) && ( nvp
!= NULLVP
))
904 error
= copyout(buf
, buffer
, len
);
908 kfree(buf
, buffersize
);
914 proc_pidworkqueueinfo(proc_t p
, struct proc_workqueueinfo
*pwqinfo
)
918 bzero(pwqinfo
, sizeof(struct proc_workqueueinfo
));
920 error
= fill_procworkqueue(p
, pwqinfo
);
927 /********************************** proc_pidinfo ********************************/
931 proc_pidinfo(int pid
, int flavor
, uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
)
933 struct proc
* p
= PROC_NULL
;
937 int refheld
= 0, shortversion
= 0;
942 case PROC_PIDLISTFDS
:
943 size
= PROC_PIDLISTFD_SIZE
;
944 if (buffer
== (user_addr_t
)0)
947 case PROC_PIDTBSDINFO
:
948 size
= PROC_PIDTBSDINFO_SIZE
;
950 case PROC_PIDTASKINFO
:
951 size
= PROC_PIDTASKINFO_SIZE
;
953 case PROC_PIDTASKALLINFO
:
954 size
= PROC_PIDTASKALLINFO_SIZE
;
956 case PROC_PIDTHREADINFO
:
957 size
= PROC_PIDTHREADINFO_SIZE
;
959 case PROC_PIDLISTTHREADS
:
960 size
= PROC_PIDLISTTHREADS_SIZE
;
962 case PROC_PIDREGIONINFO
:
963 size
= PROC_PIDREGIONINFO_SIZE
;
965 case PROC_PIDREGIONPATHINFO
:
966 size
= PROC_PIDREGIONPATHINFO_SIZE
;
968 case PROC_PIDVNODEPATHINFO
:
969 size
= PROC_PIDVNODEPATHINFO_SIZE
;
971 case PROC_PIDTHREADPATHINFO
:
972 size
= PROC_PIDTHREADPATHINFO_SIZE
;
974 case PROC_PIDPATHINFO
:
977 case PROC_PIDWORKQUEUEINFO
:
978 /* kernel does not have workq info */
982 size
= PROC_PIDWORKQUEUEINFO_SIZE
;
984 case PROC_PIDT_SHORTBSDINFO
:
985 size
= PROC_PIDT_SHORTBSDINFO_SIZE
;
987 case PROC_PIDLISTFILEPORTS
:
988 size
= PROC_PIDLISTFILEPORTS_SIZE
;
989 if (buffer
== (user_addr_t
)0)
996 if (buffersize
< size
)
999 if ((flavor
== PROC_PIDPATHINFO
) && (buffersize
> PROC_PIDPATHINFO_MAXSIZE
)) {
1003 if ((flavor
!= PROC_PIDTBSDINFO
) && (flavor
!= PROC_PIDPATHINFO
) && (flavor
!= PROC_PIDT_SHORTBSDINFO
)) {
1004 if ((p
= proc_find(pid
)) == PROC_NULL
) {
1010 /* Do we have permission to look into this ? */
1011 if ((error
= proc_security_policy(p
)) != 0) {
1017 case PROC_PIDLISTFDS
: {
1018 error
= proc_pidfdlist(p
, buffer
, buffersize
, retval
);
1022 case PROC_PIDT_SHORTBSDINFO
:
1024 case PROC_PIDTBSDINFO
: {
1025 struct proc_bsdinfo pbsd
;
1026 struct proc_bsdshortinfo pbsd_short
;
1032 if (p
== PROC_NULL
) {
1034 p
= proc_find_zombref(pid
);
1042 /* Do we have permission to look into this ? */
1043 if ((flavor
!= PROC_PIDT_SHORTBSDINFO
) && ((error
= proc_security_policy(p
)) != 0)) {
1046 proc_drop_zombref(p
);
1052 if (shortversion
!= 0) {
1053 error
= proc_pidshortbsdinfo(p
, &pbsd_short
, zombie
);
1055 error
= proc_pidbsdinfo(p
, &pbsd
, zombie
);
1059 proc_drop_zombref(p
);
1064 if (shortversion
!= 0) {
1065 error
= copyout(&pbsd_short
, buffer
, sizeof(struct proc_bsdshortinfo
));
1067 *retval
= sizeof(struct proc_bsdshortinfo
);
1069 error
= copyout(&pbsd
, buffer
, sizeof(struct proc_bsdinfo
));
1071 *retval
= sizeof(struct proc_bsdinfo
);
1077 case PROC_PIDTASKINFO
: {
1078 struct proc_taskinfo ptinfo
;
1080 error
= proc_pidtaskinfo(p
, &ptinfo
);
1082 error
= copyout(&ptinfo
, buffer
, sizeof(struct proc_taskinfo
));
1084 *retval
= sizeof(struct proc_taskinfo
);
1089 case PROC_PIDTASKALLINFO
: {
1090 struct proc_taskallinfo pall
;
1092 error
= proc_pidbsdinfo(p
, &pall
.pbsd
, 0);
1093 error
= proc_pidtaskinfo(p
, &pall
.ptinfo
);
1095 error
= copyout(&pall
, buffer
, sizeof(struct proc_taskallinfo
));
1097 *retval
= sizeof(struct proc_taskallinfo
);
1102 case PROC_PIDTHREADINFO
:{
1103 struct proc_threadinfo pthinfo
;
1105 error
= proc_pidthreadinfo(p
, arg
, &pthinfo
);
1107 error
= copyout(&pthinfo
, buffer
, sizeof(struct proc_threadinfo
));
1109 *retval
= sizeof(struct proc_threadinfo
);
1114 case PROC_PIDLISTTHREADS
:{
1115 error
= proc_pidlistthreads(p
, buffer
, buffersize
, retval
);
1119 case PROC_PIDREGIONINFO
:{
1120 error
= proc_pidregioninfo(p
, arg
, buffer
, buffersize
, retval
);
1125 case PROC_PIDREGIONPATHINFO
:{
1126 error
= proc_pidregionpathinfo(p
, arg
, buffer
, buffersize
, retval
);
1130 case PROC_PIDVNODEPATHINFO
:{
1131 error
= proc_pidvnodepathinfo(p
, arg
, buffer
, buffersize
, retval
);
1136 case PROC_PIDTHREADPATHINFO
:{
1137 struct proc_threadwithpathinfo pinfo
;
1139 error
= proc_pidthreadpathinfo(p
, arg
, &pinfo
);
1141 error
= copyout((caddr_t
)&pinfo
, buffer
, sizeof(struct proc_threadwithpathinfo
));
1143 *retval
= sizeof(struct proc_threadwithpathinfo
);
1148 case PROC_PIDPATHINFO
: {
1150 if (p
== PROC_NULL
) {
1155 error
= proc_pidpathinfo(p
, arg
, buffer
, buffersize
, retval
);
1160 case PROC_PIDWORKQUEUEINFO
:{
1161 struct proc_workqueueinfo pwqinfo
;
1163 error
= proc_pidworkqueueinfo(p
, &pwqinfo
);
1165 error
= copyout(&pwqinfo
, buffer
, sizeof(struct proc_workqueueinfo
));
1167 *retval
= sizeof(struct proc_workqueueinfo
);
1172 case PROC_PIDLISTFILEPORTS
: {
1173 error
= proc_pidfileportlist(p
, buffer
, buffersize
,
1190 pid_vnodeinfo(vnode_t vp
, uint32_t vid
, struct fileproc
* fp
, int closeonexec
, user_addr_t buffer
, __unused
uint32_t buffersize
, int32_t * retval
)
1192 struct vnode_fdinfo vfi
;
1195 if ((error
= vnode_getwithvid(vp
, vid
)) != 0) {
1198 bzero(&vfi
, sizeof(struct vnode_fdinfo
));
1199 fill_fileinfo(fp
, closeonexec
, &vfi
.pfi
);
1200 error
= fill_vnodeinfo(vp
, &vfi
.pvi
);
1203 error
= copyout((caddr_t
)&vfi
, buffer
, sizeof(struct vnode_fdinfo
));
1205 *retval
= sizeof(struct vnode_fdinfo
);
1211 pid_vnodeinfopath(vnode_t vp
, uint32_t vid
, struct fileproc
* fp
, int closeonexec
, user_addr_t buffer
, __unused
uint32_t buffersize
, int32_t * retval
)
1213 struct vnode_fdinfowithpath vfip
;
1214 int count
, error
= 0;
1216 if ((error
= vnode_getwithvid(vp
, vid
)) != 0) {
1219 bzero(&vfip
, sizeof(struct vnode_fdinfowithpath
));
1220 fill_fileinfo(fp
, closeonexec
, &vfip
.pfi
);
1221 error
= fill_vnodeinfo(vp
, &vfip
.pvip
.vip_vi
) ;
1224 vn_getpath(vp
, &vfip
.pvip
.vip_path
[0], &count
);
1225 vfip
.pvip
.vip_path
[MAXPATHLEN
-1] = 0;
1227 error
= copyout((caddr_t
)&vfip
, buffer
, sizeof(struct vnode_fdinfowithpath
));
1229 *retval
= sizeof(struct vnode_fdinfowithpath
);
1236 fill_fileinfo(struct fileproc
* fp
, int closeonexec
, struct proc_fileinfo
* fproc
)
1238 fproc
->fi_openflags
= fp
->f_fglob
->fg_flag
;
1239 fproc
->fi_status
= 0;
1240 fproc
->fi_offset
= fp
->f_fglob
->fg_offset
;
1241 fproc
->fi_type
= fp
->f_fglob
->fg_type
;
1242 if (fp
->f_fglob
->fg_count
)
1243 fproc
->fi_status
|= PROC_FP_SHARED
;
1244 if (closeonexec
!= 0)
1245 fproc
->fi_status
|= PROC_FP_CLEXEC
;
1251 fill_vnodeinfo(vnode_t vp
, struct vnode_info
*vinfo
)
1253 vfs_context_t context
;
1257 context
= vfs_context_create((vfs_context_t
)0);
1258 error
= vn_stat(vp
, &sb
, NULL
, 1, context
);
1259 (void)vfs_context_rele(context
);
1261 munge_vinfo_stat(&sb
, &vinfo
->vi_stat
);
1266 if (vp
->v_mount
!= dead_mountp
) {
1267 vinfo
->vi_fsid
= vp
->v_mount
->mnt_vfsstat
.f_fsid
;
1269 vinfo
->vi_fsid
.val
[0] = 0;
1270 vinfo
->vi_fsid
.val
[1] = 0;
1272 vinfo
->vi_type
= vp
->v_type
;
1278 pid_socketinfo(socket_t so
, struct fileproc
*fp
, int closeonexec
, user_addr_t buffer
, __unused
uint32_t buffersize
, int32_t * retval
)
1281 struct socket_fdinfo s
;
1284 bzero(&s
, sizeof(struct socket_fdinfo
));
1285 fill_fileinfo(fp
, closeonexec
, &s
.pfi
);
1286 if ((error
= fill_socketinfo(so
, &s
.psi
)) == 0) {
1287 if ((error
= copyout(&s
, buffer
, sizeof(struct socket_fdinfo
))) == 0)
1288 *retval
= sizeof(struct socket_fdinfo
);
1298 pid_pseminfo(struct psemnode
*psem
, struct fileproc
*fp
, int closeonexec
, user_addr_t buffer
, __unused
uint32_t buffersize
, int32_t * retval
)
1300 struct psem_fdinfo pseminfo
;
1303 bzero(&pseminfo
, sizeof(struct psem_fdinfo
));
1304 fill_fileinfo(fp
, closeonexec
, &pseminfo
.pfi
);
1306 if ((error
= fill_pseminfo(psem
, &pseminfo
.pseminfo
)) == 0) {
1307 if ((error
= copyout(&pseminfo
, buffer
, sizeof(struct psem_fdinfo
))) == 0)
1308 *retval
= sizeof(struct psem_fdinfo
);
1315 pid_pshminfo(struct pshmnode
*pshm
, struct fileproc
*fp
, int closeonexec
, user_addr_t buffer
, __unused
uint32_t buffersize
, int32_t * retval
)
1317 struct pshm_fdinfo pshminfo
;
1320 bzero(&pshminfo
, sizeof(struct pshm_fdinfo
));
1321 fill_fileinfo(fp
, closeonexec
, &pshminfo
.pfi
);
1323 if ((error
= fill_pshminfo(pshm
, &pshminfo
.pshminfo
)) == 0) {
1324 if ((error
= copyout(&pshminfo
, buffer
, sizeof(struct pshm_fdinfo
))) == 0)
1325 *retval
= sizeof(struct pshm_fdinfo
);
1332 pid_pipeinfo(struct pipe
* p
, struct fileproc
*fp
, int closeonexec
, user_addr_t buffer
, __unused
uint32_t buffersize
, int32_t * retval
)
1334 struct pipe_fdinfo pipeinfo
;
1337 bzero(&pipeinfo
, sizeof(struct pipe_fdinfo
));
1338 fill_fileinfo(fp
, closeonexec
, &pipeinfo
.pfi
);
1339 if ((error
= fill_pipeinfo(p
, &pipeinfo
.pipeinfo
)) == 0) {
1340 if ((error
= copyout(&pipeinfo
, buffer
, sizeof(struct pipe_fdinfo
))) == 0)
1341 *retval
= sizeof(struct pipe_fdinfo
);
1348 pid_kqueueinfo(struct kqueue
* kq
, struct fileproc
*fp
, int closeonexec
, user_addr_t buffer
, __unused
uint32_t buffersize
, int32_t * retval
)
1350 struct kqueue_fdinfo kqinfo
;
1353 bzero(&kqinfo
, sizeof(struct kqueue_fdinfo
));
1355 fill_fileinfo(fp
, closeonexec
, &kqinfo
.pfi
);
1357 if ((error
= fill_kqueueinfo(kq
, &kqinfo
.kqueueinfo
)) == 0) {
1358 if ((error
= copyout(&kqinfo
, buffer
, sizeof(struct kqueue_fdinfo
))) == 0)
1359 *retval
= sizeof(struct kqueue_fdinfo
);
1366 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
)
1373 /************************** proc_pidfdinfo routine ***************************/
1375 proc_pidfdinfo(int pid
, int flavor
, int fd
, user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
)
1378 int error
= ENOTSUP
;
1379 struct fileproc
* fp
;
1381 int closeonexec
= 0;
1384 case PROC_PIDFDVNODEINFO
:
1385 size
= PROC_PIDFDVNODEINFO_SIZE
;
1387 case PROC_PIDFDVNODEPATHINFO
:
1388 size
= PROC_PIDFDVNODEPATHINFO_SIZE
;
1390 case PROC_PIDFDSOCKETINFO
:
1391 size
= PROC_PIDFDSOCKETINFO_SIZE
;
1393 case PROC_PIDFDPSEMINFO
:
1394 size
= PROC_PIDFDPSEMINFO_SIZE
;
1396 case PROC_PIDFDPSHMINFO
:
1397 size
= PROC_PIDFDPSHMINFO_SIZE
;
1399 case PROC_PIDFDPIPEINFO
:
1400 size
= PROC_PIDFDPIPEINFO_SIZE
;
1402 case PROC_PIDFDKQUEUEINFO
:
1403 size
= PROC_PIDFDKQUEUEINFO_SIZE
;
1405 case PROC_PIDFDATALKINFO
:
1406 size
= PROC_PIDFDATALKINFO_SIZE
;
1414 if (buffersize
< size
)
1417 if ((p
= proc_find(pid
)) == PROC_NULL
) {
1421 /* Do we have permission to look into this ? */
1422 if ((error
= proc_security_policy(p
)) != 0) {
1427 case PROC_PIDFDVNODEINFO
: {
1431 if ((error
= fp_getfvpandvid(p
, fd
, &fp
, &vp
, &vid
)) !=0) {
1434 /* no need to be under the fdlock */
1435 closeonexec
= p
->p_fd
->fd_ofileflags
[fd
] & UF_EXCLOSE
;
1436 error
= pid_vnodeinfo(vp
, vid
, fp
, closeonexec
, buffer
, buffersize
, retval
);
1440 case PROC_PIDFDVNODEPATHINFO
: {
1444 if ((error
= fp_getfvpandvid(p
, fd
, &fp
, &vp
, &vid
)) !=0) {
1448 /* no need to be under the fdlock */
1449 closeonexec
= p
->p_fd
->fd_ofileflags
[fd
] & UF_EXCLOSE
;
1450 error
= pid_vnodeinfopath(vp
, vid
, fp
, closeonexec
, buffer
, buffersize
, retval
);
1454 case PROC_PIDFDSOCKETINFO
: {
1457 if ((error
= fp_getfsock(p
, fd
, &fp
, &so
)) !=0) {
1460 /* no need to be under the fdlock */
1461 closeonexec
= p
->p_fd
->fd_ofileflags
[fd
] & UF_EXCLOSE
;
1462 error
= pid_socketinfo(so
, fp
, closeonexec
, buffer
, buffersize
, retval
);
1466 case PROC_PIDFDPSEMINFO
: {
1467 struct psemnode
* psem
;
1469 if ((error
= fp_getfpsem(p
, fd
, &fp
, &psem
)) !=0) {
1472 /* no need to be under the fdlock */
1473 closeonexec
= p
->p_fd
->fd_ofileflags
[fd
] & UF_EXCLOSE
;
1474 error
= pid_pseminfo(psem
, fp
, closeonexec
, buffer
, buffersize
, retval
);
1478 case PROC_PIDFDPSHMINFO
: {
1479 struct pshmnode
* pshm
;
1481 if ((error
= fp_getfpshm(p
, fd
, &fp
, &pshm
)) !=0) {
1484 /* no need to be under the fdlock */
1485 closeonexec
= p
->p_fd
->fd_ofileflags
[fd
] & UF_EXCLOSE
;
1486 error
= pid_pshminfo(pshm
, fp
, closeonexec
, buffer
, buffersize
, retval
);
1490 case PROC_PIDFDPIPEINFO
: {
1491 struct pipe
* cpipe
;
1493 if ((error
= fp_getfpipe(p
, fd
, &fp
, &cpipe
)) !=0) {
1496 /* no need to be under the fdlock */
1497 closeonexec
= p
->p_fd
->fd_ofileflags
[fd
] & UF_EXCLOSE
;
1498 error
= pid_pipeinfo(cpipe
, fp
, closeonexec
, buffer
, buffersize
, retval
);
1502 case PROC_PIDFDKQUEUEINFO
: {
1505 if ((error
= fp_getfkq(p
, fd
, &fp
, &kq
)) !=0) {
1508 /* no need to be under the fdlock */
1509 closeonexec
= p
->p_fd
->fd_ofileflags
[fd
] & UF_EXCLOSE
;
1510 error
= pid_kqueueinfo(kq
, fp
, closeonexec
, buffer
, buffersize
, retval
);
1515 case PROC_PIDFDATALKINFO
: {
1518 if ((error
= fp_getfatalk(p
, fd
, &fp
, &at
)) !=0) {
1522 /* no need to be under the fdlock */
1523 closeonexec
= p
->p_fd
->fd_ofileflags
[fd
] & UF_EXCLOSE
;
1524 error
= pid_atalkinfo(at
, fp
, closeonexec
, buffer
, buffersize
, retval
);
1534 fp_drop(p
, fd
, fp
, 0);
1542 * Helper function for proc_pidfileportinfo
1545 struct fileport_info_args
{
1547 user_addr_t fia_buffer
;
1548 uint32_t fia_buffersize
;
1549 int32_t *fia_retval
;
1552 static kern_return_t
1553 proc_fileport_info(__unused mach_port_name_t name
,
1554 struct fileglob
*fg
, void *arg
)
1556 struct fileport_info_args
*fia
= arg
;
1557 struct fileproc __fileproc
, *fp
= &__fileproc
;
1560 bzero(fp
, sizeof (*fp
));
1563 switch (fia
->fia_flavor
) {
1564 case PROC_PIDFILEPORTVNODEPATHINFO
: {
1567 if (fg
->fg_type
!= DTYPE_VNODE
) {
1571 vp
= (struct vnode
*)fg
->fg_data
;
1572 error
= pid_vnodeinfopath(vp
, vnode_vid(vp
), fp
, 0,
1573 fia
->fia_buffer
, fia
->fia_buffersize
, fia
->fia_retval
);
1576 case PROC_PIDFILEPORTSOCKETINFO
: {
1579 if (fg
->fg_type
!= DTYPE_SOCKET
) {
1583 so
= (socket_t
)fg
->fg_data
;
1584 error
= pid_socketinfo(so
, fp
, 0,
1585 fia
->fia_buffer
, fia
->fia_buffersize
, fia
->fia_retval
);
1588 case PROC_PIDFILEPORTPSHMINFO
: {
1589 struct pshmnode
*pshm
;
1591 if (fg
->fg_type
!= DTYPE_PSXSHM
) {
1592 error
= EBADF
; /* ick - mirror fp_getfpshm */
1595 pshm
= (struct pshmnode
*)fg
->fg_data
;
1596 error
= pid_pshminfo(pshm
, fp
, 0,
1597 fia
->fia_buffer
, fia
->fia_buffersize
, fia
->fia_retval
);
1600 case PROC_PIDFILEPORTPIPEINFO
: {
1603 if (fg
->fg_type
!= DTYPE_PIPE
) {
1604 error
= EBADF
; /* ick - mirror fp_getfpipe */
1607 cpipe
= (struct pipe
*)fg
->fg_data
;
1608 error
= pid_pipeinfo(cpipe
, fp
, 0,
1609 fia
->fia_buffer
, fia
->fia_buffersize
, fia
->fia_retval
);
1620 /************************* proc_pidfileportinfo routine *********************/
1622 proc_pidfileportinfo(int pid
, int flavor
, mach_port_name_t name
,
1623 user_addr_t buffer
, uint32_t buffersize
, int32_t *retval
)
1626 int error
= ENOTSUP
;
1628 struct fileport_info_args fia
;
1630 /* fileport types are restricted by filetype_issendable() */
1633 case PROC_PIDFILEPORTVNODEPATHINFO
:
1634 size
= PROC_PIDFILEPORTVNODEPATHINFO_SIZE
;
1636 case PROC_PIDFILEPORTSOCKETINFO
:
1637 size
= PROC_PIDFILEPORTSOCKETINFO_SIZE
;
1639 case PROC_PIDFILEPORTPSHMINFO
:
1640 size
= PROC_PIDFILEPORTPSHMINFO_SIZE
;
1642 case PROC_PIDFILEPORTPIPEINFO
:
1643 size
= PROC_PIDFILEPORTPIPEINFO_SIZE
;
1649 if (buffersize
< size
)
1651 if ((p
= proc_find(pid
)) == PROC_NULL
) {
1655 if ((error
= proc_security_policy(p
)) != 0) {
1659 fia
.fia_flavor
= flavor
;
1660 fia
.fia_buffer
= buffer
;
1661 fia
.fia_buffersize
= buffersize
;
1662 fia
.fia_retval
= retval
;
1664 if (fileport_invoke(p
->task
, name
,
1665 proc_fileport_info
, &fia
, &error
) != KERN_SUCCESS
)
1674 proc_security_policy(proc_t p
)
1676 kauth_cred_t my_cred
;
1679 my_cred
= kauth_cred_proc_ref(p
);
1680 uid
= kauth_cred_getuid(my_cred
) ;
1681 kauth_cred_unref(&my_cred
);
1683 if ((uid
!= kauth_cred_getuid(kauth_cred_get()))
1684 && suser(kauth_cred_get(), (u_short
*)0)) {
1692 proc_kernmsgbuf(user_addr_t buffer
, uint32_t buffersize
, int32_t * retval
)
1694 if (suser(kauth_cred_get(), (u_short
*)0) == 0) {
1695 return(log_dmesg(buffer
, buffersize
, retval
));
1700 /* ********* process control sets on self only */
1702 proc_setcontrol(int pid
, int flavor
, uint64_t arg
, user_addr_t buffer
, uint32_t buffersize
, __unused
int32_t * retval
)
1704 struct proc
* pself
= PROC_NULL
;
1706 uint32_t pcontrol
= (uint32_t)arg
;
1707 struct uthread
*ut
= NULL
;
1710 pself
= current_proc();
1711 if (pid
!= pself
->p_pid
)
1716 case PROC_SELFSET_PCONTROL
: {
1717 if (pcontrol
> P_PCMAX
)
1720 /* reset existing control setting while retaining action state */
1721 pself
->p_pcaction
&= PROC_ACTION_MASK
;
1722 /* set new control state */
1723 pself
->p_pcaction
|= pcontrol
;
1728 case PROC_SELFSET_THREADNAME
: {
1729 /* PROC_SELFSET_THREADNAME_SIZE = (MAXTHREADNAMESIZE -1) */
1730 if(buffersize
> PROC_SELFSET_THREADNAME_SIZE
)
1731 return ENAMETOOLONG
;
1732 ut
= current_uthread();
1736 ut
->pth_name
= (char*)kalloc(MAXTHREADNAMESIZE
);
1740 bzero(ut
->pth_name
, MAXTHREADNAMESIZE
);
1741 error
= copyin(buffer
, ut
->pth_name
, buffersize
);
1745 case PROC_SELFSET_VMRSRCOWNER
: {
1746 /* need to to be superuser */
1747 if (suser(kauth_cred_get(), (u_short
*)0) != 0) {
1753 /* reset existing control setting while retaining action state */
1754 pself
->p_lflag
|= P_LVMRSRCOWNER
;
1769 * copy stat64 structure into vinfo_stat structure.
1772 munge_vinfo_stat(struct stat64
*sbp
, struct vinfo_stat
*vsbp
)
1774 bzero(vsbp
, sizeof(struct vinfo_stat
));
1776 vsbp
->vst_dev
= sbp
->st_dev
;
1777 vsbp
->vst_mode
= sbp
->st_mode
;
1778 vsbp
->vst_nlink
= sbp
->st_nlink
;
1779 vsbp
->vst_ino
= sbp
->st_ino
;
1780 vsbp
->vst_uid
= sbp
->st_uid
;
1781 vsbp
->vst_gid
= sbp
->st_gid
;
1782 vsbp
->vst_atime
= sbp
->st_atimespec
.tv_sec
;
1783 vsbp
->vst_atimensec
= sbp
->st_atimespec
.tv_nsec
;
1784 vsbp
->vst_mtime
= sbp
->st_mtimespec
.tv_sec
;
1785 vsbp
->vst_mtimensec
= sbp
->st_mtimespec
.tv_nsec
;
1786 vsbp
->vst_ctime
= sbp
->st_ctimespec
.tv_sec
;
1787 vsbp
->vst_ctimensec
= sbp
->st_ctimespec
.tv_nsec
;
1788 vsbp
->vst_birthtime
= sbp
->st_birthtimespec
.tv_sec
;
1789 vsbp
->vst_birthtimensec
= sbp
->st_birthtimespec
.tv_nsec
;
1790 vsbp
->vst_size
= sbp
->st_size
;
1791 vsbp
->vst_blocks
= sbp
->st_blocks
;
1792 vsbp
->vst_blksize
= sbp
->st_blksize
;
1793 vsbp
->vst_flags
= sbp
->st_flags
;
1794 vsbp
->vst_gen
= sbp
->st_gen
;
1795 vsbp
->vst_rdev
= sbp
->st_rdev
;
1796 vsbp
->vst_qspare
[0] = sbp
->st_qspare
[0];
1797 vsbp
->vst_qspare
[1] = sbp
->st_qspare
[1];