71#include <sys/capsicum.h>
74#include <sys/filedesc.h>
75#include <sys/kernel.h>
80#include <sys/procdesc.h>
81#include <sys/resourcevar.h>
83#include <sys/sysproto.h>
84#include <sys/sysctl.h>
89#include <security/audit/audit.h>
93FEATURE(process_descriptors,
"Process Descriptors");
116 .fo_flags = DFLAG_PASSABLE,
131 error =
fget(td,
fd, rightsp, &fp);
134 if (fp->f_type != DTYPE_PROCDESC) {
140 if (pd->pd_proc != NULL) {
160 KASSERT(fp_procdesc->f_type == DTYPE_PROCDESC,
161 (
"procdesc_pid: !procdesc"));
163 pd = fp_procdesc->f_data;
176 error =
fget(td,
fd, rightsp, &fp);
179 if (fp->f_type != DTYPE_PROCDESC) {
198 AUDIT_ARG_FD(uap->fd);
201 error = copyout(&pid, uap->pidp,
sizeof(pid));
216 pd =
malloc(
sizeof(*pd), M_PROCDESC, M_WAITOK | M_ZERO);
218 pd->pd_pid = p->p_pid;
221 if (
flags & PD_DAEMON)
222 pd->pd_flags |= PDF_DAEMON;
223 PROCDESC_LOCK_INIT(pd);
230 refcount_init(&pd->pd_refcount, 2);
238 int flags,
struct filecaps *fcaps)
243 if (
flags & PD_CLOEXEC)
246 return (
falloc_caps(td, resultfp, resultfd, fflags, fcaps));
269 if (refcount_release(&pd->pd_refcount)) {
270 KASSERT(pd->pd_proc == NULL,
271 (
"procdesc_free: pd_proc != NULL"));
272 KASSERT((pd->pd_flags & PDF_CLOSED),
273 (
"procdesc_free: !PDF_CLOSED"));
276 PROCDESC_LOCK_DESTROY(pd);
277 free(pd, M_PROCDESC);
292 PROC_LOCK_ASSERT(p, MA_OWNED);
293 KASSERT(p->p_procdesc != NULL, (
"procdesc_exit: p_procdesc NULL"));
298 KASSERT((pd->pd_flags & PDF_CLOSED) == 0 || p->p_pptr == p->p_reaper,
299 (
"procdesc_exit: closed && parent not reaper"));
301 pd->pd_flags |= PDF_EXITED;
302 pd->pd_xstat = KW_EXITCODE(p->p_xexit, p->p_xsig);
310 if (pd->pd_flags & PDF_CLOSED) {
313 p->p_procdesc = NULL;
317 if (pd->pd_flags & PDF_SELECTED) {
318 pd->pd_flags &= ~PDF_SELECTED;
321 KNOTE_LOCKED(&pd->pd_selinfo.si_note, NOTE_EXIT);
336 KASSERT(p->p_procdesc != NULL, (
"procdesc_reap: p_procdesc == NULL"));
340 p->p_procdesc = NULL;
356 KASSERT(fp->f_type == DTYPE_PROCDESC, (
"procdesc_close: !procdesc"));
364 pd->pd_flags |= PDF_CLOSED;
375 AUDIT_ARG_PROCESS(p);
376 if (p->p_state == PRS_ZOMBIE) {
393 p->p_procdesc = NULL;
401 p->p_sigparent = SIGCHLD;
402 if ((p->p_flag & P_TRACED) == 0) {
406 p->p_oppid = p->p_reaper->p_pid;
409 if ((pd->pd_flags & PDF_DAEMON) == 0)
433 if (pd->pd_flags & PDF_EXITED)
437 pd->pd_flags |= PDF_SELECTED;
448 pd = kn->kn_fp->f_data;
458 pd = kn->kn_fp->f_data;
464 event = pd->pd_flags & PDF_EXITED ? NOTE_EXIT : 0;
467 event = (u_int)hint & NOTE_PCTRLMASK;
471 if (kn->kn_sfflags & event)
472 kn->kn_fflags |= event;
475 if (event == NOTE_EXIT) {
476 kn->kn_flags |= EV_EOF | EV_ONESHOT;
477 if (kn->kn_fflags & NOTE_EXIT)
478 kn->kn_data = pd->pd_xstat;
479 if (kn->kn_fflags == 0)
480 kn->kn_flags |= EV_DROP;
484 return (kn->kn_fflags != 0);
499 switch (kn->kn_filter) {
500 case EVFILT_PROCDESC:
502 kn->kn_flags |= EV_CLEAR;
514 struct timeval pstart, boottime;
521 bzero(sb,
sizeof(*sb));
524 if (pd->pd_proc != NULL) {
525 PROC_LOCK(pd->pd_proc);
526 AUDIT_ARG_PROCESS(pd->pd_proc);
529 pstart = pd->pd_proc->p_stats->p_start;
532 TIMEVAL_TO_TIMESPEC(&pstart, &sb->st_birthtim);
533 sb->st_atim = sb->st_birthtim;
534 sb->st_ctim = sb->st_birthtim;
535 sb->st_mtim = sb->st_birthtim;
536 if (pd->pd_proc->p_state != PRS_ZOMBIE)
537 sb->st_mode = S_IFREG | S_IRWXU;
539 sb->st_mode = S_IFREG;
540 sb->st_uid = pd->pd_proc->p_ucred->cr_ruid;
541 sb->st_gid = pd->pd_proc->p_ucred->cr_rgid;
542 PROC_UNLOCK(pd->pd_proc);
544 sb->st_mode = S_IFREG;
551 struct filedesc *fdp)
553 struct procdesc *pdp;
555 kif->kf_type = KF_TYPE_PROCDESC;
557 kif->kf_un.kf_proc.kf_pid = pdp->pd_pid;
int invfo_ioctl(struct file *fp, u_long com, void *data, struct ucred *active_cred, struct thread *td)
int invfo_truncate(struct file *fp, off_t length, struct ucred *active_cred, struct thread *td)
int invfo_chown(struct file *fp, uid_t uid, gid_t gid, struct ucred *active_cred, struct thread *td)
int fget(struct thread *td, int fd, cap_rights_t *rightsp, struct file **fpp)
struct fileops badfileops
void finit(struct file *fp, u_int flag, short type, void *data, struct fileops *ops)
int invfo_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio, struct uio *trl_uio, off_t offset, size_t nbytes, off_t *sent, int flags, struct thread *td)
int invfo_rdwr(struct file *fp, struct uio *uio, struct ucred *active_cred, int flags, struct thread *td)
int falloc_caps(struct thread *td, struct file **resultfp, int *resultfd, int flags, struct filecaps *fcaps)
int invfo_chmod(struct file *fp, mode_t mode, struct ucred *active_cred, struct thread *td)
void knlist_remove(struct knlist *knl, struct knote *kn, int islocked)
void knlist_add(struct knlist *knl, struct knote *kn, int islocked)
void knlist_destroy(struct knlist *knl)
void knote(struct knlist *list, long hint, int lockflags)
void knlist_init_mtx(struct knlist *knl, struct mtx *lock)
void proc_clear_orphan(struct proc *p)
void proc_add_orphan(struct proc *child, struct proc *parent)
void proc_reap(struct thread *td, struct proc *p, int *status, int options)
void proc_reparent(struct proc *child, struct proc *parent, bool set_oppid)
void *() malloc(size_t size, struct malloc_type *mtp, int flags)
void free(void *addr, struct malloc_type *mtp)
struct sx __exclusive_cache_line proctree_lock
void kern_psignal(struct proc *p, int sig)
void getboottime(struct timeval *boottime)
void timevaladd(struct timeval *t1, const struct timeval *t2)
__read_mostly cap_rights_t cap_pdgetpid_rights
void selrecord(struct thread *selector, struct selinfo *sip)
void selwakeup(struct selinfo *sip)
FEATURE(process_descriptors, "Process Descriptors")
static void procdesc_free(struct procdesc *pd)
static fo_stat_t procdesc_stat
int procdesc_falloc(struct thread *td, struct file **resultfp, int *resultfd, int flags, struct filecaps *fcaps)
pid_t procdesc_pid(struct file *fp_procdesc)
static int procdesc_kqops_event(struct knote *kn, long hint)
int procdesc_find(struct thread *td, int fd, cap_rights_t *rightsp, struct proc **p)
static void procdesc_kqops_detach(struct knote *kn)
void procdesc_new(struct proc *p, int flags)
MALLOC_DEFINE(M_PROCDESC, "procdesc", "process descriptors")
void procdesc_finit(struct procdesc *pdp, struct file *fp)
static fo_kqfilter_t procdesc_kqfilter
void procdesc_reap(struct proc *p)
static fo_poll_t procdesc_poll
static fo_fill_kinfo_t procdesc_fill_kinfo
static fo_close_t procdesc_close
int kern_pdgetpid(struct thread *td, int fd, cap_rights_t *rightsp, pid_t *pidp)
int procdesc_exit(struct proc *p)
int sys_pdgetpid(struct thread *td, struct pdgetpid_args *uap)
static struct filterops procdesc_kqops
static struct fileops procdesc_ops