61 #include <sys/cdefs.h> 
   64 #include "opt_procdesc.h" 
   66 #include <sys/param.h> 
   67 #include <sys/capability.h> 
   68 #include <sys/fcntl.h> 
   70 #include <sys/filedesc.h> 
   71 #include <sys/kernel.h> 
   73 #include <sys/mutex.h> 
   76 #include <sys/procdesc.h> 
   77 #include <sys/resourcevar.h> 
   79 #include <sys/sysproto.h> 
   80 #include <sys/sysctl.h> 
   81 #include <sys/systm.h> 
   82 #include <sys/ucred.h> 
   84 #include <security/audit/audit.h> 
   90 FEATURE(process_descriptors, 
"Process Descriptors");
 
   92 static uma_zone_t procdesc_zone;
 
   94 static fo_rdwr_t        procdesc_read;
 
   95 static fo_rdwr_t        procdesc_write;
 
   96 static fo_truncate_t    procdesc_truncate;
 
   97 static fo_ioctl_t       procdesc_ioctl;
 
   98 static fo_poll_t        procdesc_poll;
 
   99 static fo_kqfilter_t    procdesc_kqfilter;
 
  100 static fo_stat_t        procdesc_stat;
 
  101 static fo_close_t       procdesc_close;
 
  102 static fo_chmod_t       procdesc_chmod;
 
  103 static fo_chown_t       procdesc_chown;
 
  105 static struct fileops procdesc_ops = {
 
  106         .fo_read = procdesc_read,
 
  107         .fo_write = procdesc_write,
 
  108         .fo_truncate = procdesc_truncate,
 
  109         .fo_ioctl = procdesc_ioctl,
 
  110         .fo_poll = procdesc_poll,
 
  111         .fo_kqfilter = procdesc_kqfilter,
 
  112         .fo_stat = procdesc_stat,
 
  113         .fo_close = procdesc_close,
 
  114         .fo_chmod = procdesc_chmod,
 
  115         .fo_chown = procdesc_chown,
 
  116         .fo_flags = DFLAG_PASSABLE,
 
  125 procdesc_init(
void *
dummy __unused)
 
  128         procdesc_zone = uma_zcreate(
"procdesc", 
sizeof(
struct procdesc),
 
  129             NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
 
  130         if (procdesc_zone == NULL)
 
  131                 panic(
"procdesc_init: procdesc_zone not initialized");
 
  133 SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_ANY, procdesc_init, NULL);
 
  140 procdesc_find(
struct thread *td, 
int fd, cap_rights_t rights,
 
  147         error = 
fget(td, fd, rights, &fp);
 
  150         if (fp->f_type != DTYPE_PROCDESC) {
 
  156         if (pd->pd_proc != NULL) {
 
  172 procdesc_pid(
struct file *fp_procdesc)
 
  176         KASSERT(fp_procdesc->f_type == DTYPE_PROCDESC,
 
  177            (
"procdesc_pid: !procdesc"));
 
  179         pd = fp_procdesc->f_data;
 
  187 kern_pdgetpid(
struct thread *td, 
int fd, cap_rights_t rights, pid_t *pidp)
 
  192         error = 
fget(td, fd, rights, &fp);
 
  195         if (fp->f_type != DTYPE_PROCDESC) {
 
  199         *pidp = procdesc_pid(fp);
 
  209 sys_pdgetpid(
struct thread *td, 
struct pdgetpid_args *uap)
 
  214         AUDIT_ARG_FD(uap->fd);
 
  215         error = kern_pdgetpid(td, uap->fd, CAP_PDGETPID, &pid);
 
  217                 error = copyout(&pid, uap->pidp, 
sizeof(pid));
 
  228 procdesc_new(
struct proc *p, 
int flags)
 
  232         pd = uma_zalloc(procdesc_zone, M_WAITOK | M_ZERO);
 
  234         pd->pd_pid = p->p_pid;
 
  237         if (flags & PD_DAEMON)
 
  238                 pd->pd_flags |= PDF_DAEMON;
 
  239         PROCDESC_LOCK_INIT(pd);
 
  245         refcount_init(&pd->pd_refcount, 2);
 
  252 procdesc_finit(
struct procdesc *pdp, 
struct file *fp)
 
  255         finit(fp, FREAD | FWRITE, DTYPE_PROCDESC, pdp, &procdesc_ops);
 
  259 procdesc_free(
struct procdesc *pd)
 
  268         if (refcount_release(&pd->pd_refcount)) {
 
  269                 KASSERT(pd->pd_proc == NULL,
 
  270                     (
"procdesc_free: pd_proc != NULL"));
 
  271                 KASSERT((pd->pd_flags & PDF_CLOSED),
 
  272                     (
"procdesc_free: !PDF_CLOSED"));
 
  274                 PROCDESC_LOCK_DESTROY(pd);
 
  275                 uma_zfree(procdesc_zone, pd);
 
  285 procdesc_exit(
struct proc *p)
 
  290         PROC_LOCK_ASSERT(p, MA_OWNED);
 
  291         KASSERT(p->p_procdesc != NULL, (
"procdesc_exit: p_procdesc NULL"));
 
  296         KASSERT((pd->pd_flags & PDF_CLOSED) == 0 || p->p_pptr == 
initproc,
 
  297             (
"procdesc_exit: closed && parent not init"));
 
  299         pd->pd_flags |= PDF_EXITED;
 
  307         if (pd->pd_flags & PDF_CLOSED) {
 
  310                 p->p_procdesc = NULL;
 
  314         if (pd->pd_flags & PDF_SELECTED) {
 
  315                 pd->pd_flags &= ~PDF_SELECTED;
 
  327 procdesc_reap(
struct proc *p)
 
  332         KASSERT(p->p_procdesc != NULL, (
"procdesc_reap: p_procdesc == NULL"));
 
  345 procdesc_close(
struct file *fp, 
struct thread *td)
 
  350         KASSERT(fp->f_type == DTYPE_PROCDESC, (
"procdesc_close: !procdesc"));
 
  358         pd->pd_flags |= PDF_CLOSED;
 
  362         if (p->p_state == PRS_ZOMBIE) {
 
  380                 p->p_procdesc = NULL;
 
  387                 p->p_sigparent = SIGCHLD;
 
  389                 if ((pd->pd_flags & PD_DAEMON) == 0)
 
  403 procdesc_read(
struct file *fp, 
struct uio *uio, 
struct ucred *active_cred,
 
  404     int flags, 
struct thread *td)
 
  411 procdesc_write(
struct file *fp, 
struct uio *uio, 
struct ucred *active_cred,
 
  412     int flags, 
struct thread *td)
 
  419 procdesc_truncate(
struct file *fp, off_t length, 
struct ucred *active_cred,
 
  427 procdesc_ioctl(
struct file *fp, u_long com, 
void *data,
 
  428     struct ucred *active_cred, 
struct thread *td)
 
  435 procdesc_poll(
struct file *fp, 
int events, 
struct ucred *active_cred,
 
  444         if (pd->pd_flags & PDF_EXITED)
 
  448                 pd->pd_flags |= PDF_SELECTED;
 
  455 procdesc_kqfilter(
struct file *fp, 
struct knote *kn)
 
  462 procdesc_stat(
struct file *fp, 
struct stat *sb, 
struct ucred *active_cred,
 
  466         struct timeval pstart;
 
  473         bzero(sb, 
sizeof(*sb));
 
  476         if (pd->pd_proc != NULL) {
 
  477                 PROC_LOCK(pd->pd_proc);
 
  480                 pstart = pd->pd_proc->p_stats->p_start;
 
  482                 TIMEVAL_TO_TIMESPEC(&pstart, &sb->st_birthtim);
 
  483                 sb->st_atim = sb->st_birthtim;
 
  484                 sb->st_ctim = sb->st_birthtim;
 
  485                 sb->st_mtim = sb->st_birthtim;
 
  486                 if (pd->pd_proc->p_state != PRS_ZOMBIE)
 
  487                         sb->st_mode = S_IFREG | S_IRWXU;
 
  489                         sb->st_mode = S_IFREG;
 
  490                 sb->st_uid = pd->pd_proc->p_ucred->cr_ruid;
 
  491                 sb->st_gid = pd->pd_proc->p_ucred->cr_rgid;
 
  492                 PROC_UNLOCK(pd->pd_proc);
 
  494                 sb->st_mode = S_IFREG;
 
  500 procdesc_chmod(
struct file *fp, mode_t 
mode, 
struct ucred *active_cred,
 
  508 procdesc_chown(
struct file *fp, uid_t uid, gid_t gid, 
struct ucred *active_cred,
 
void selwakeup(struct selinfo *sip)
void selrecord(struct thread *selector, struct selinfo *sip)
void panic(const char *fmt,...)
SYSINIT(placeholder, SI_SUB_DUMMY, SI_ORDER_ANY, NULL, NULL)
void knote(struct knlist *list, long hint, int lockflags)
void kern_psignal(struct proc *p, int sig)
int fget(struct thread *td, int fd, cap_rights_t rights, struct file **fpp)
void timevaladd(struct timeval *t1, const struct timeval *t2)
void proc_reap(struct thread *td, struct proc *p, int *status, int options)
void finit(struct file *fp, u_int flag, short type, void *data, struct fileops *ops)
int sys_pdgetpid(struct thread *td, struct pdgetpid_args *uap)
void proc_reparent(struct proc *child, struct proc *parent)
FEATURE(kdtrace_hooks,"Kernel DTrace hooks which are required to load DTrace kernel modules")
struct fileops badfileops