From 679a7c6b30cb5961b6ae8204bfd02c0138af681c Mon Sep 17 00:00:00 2001 From: Jan-Simon Pendry Date: Wed, 15 Jun 1994 19:30:54 -0800 Subject: [PATCH] merge in netbsd changes. security fixes, curproc becomes symlink, misc other trash. SCCS-vsn: sys/miscfs/procfs/procfs.h 8.7 SCCS-vsn: sys/miscfs/procfs/README 8.2 SCCS-vsn: sys/miscfs/procfs/procfs_ctl.c 8.4 SCCS-vsn: sys/miscfs/procfs/procfs_mem.c 8.5 SCCS-vsn: sys/miscfs/procfs/procfs_regs.c 8.4 SCCS-vsn: sys/miscfs/procfs/procfs_subr.c 8.5 SCCS-vsn: sys/miscfs/procfs/procfs_vnops.c 8.8 SCCS-vsn: sys/miscfs/procfs/procfs_status.c 8.4 SCCS-vsn: sys/miscfs/procfs/procfs_vfsops.c 8.5 SCCS-vsn: sys/miscfs/procfs/procfs_fpregs.c 8.2 --- usr/src/sys/miscfs/procfs/procfs.h | 50 ++-- usr/src/sys/miscfs/procfs/procfs_ctl.c | 20 +- usr/src/sys/miscfs/procfs/procfs_fpregs.c | 10 +- usr/src/sys/miscfs/procfs/procfs_mem.c | 8 +- usr/src/sys/miscfs/procfs/procfs_regs.c | 10 +- usr/src/sys/miscfs/procfs/procfs_status.c | 6 +- usr/src/sys/miscfs/procfs/procfs_subr.c | 59 +++-- usr/src/sys/miscfs/procfs/procfs_vfsops.c | 18 +- usr/src/sys/miscfs/procfs/procfs_vnops.c | 273 +++++++++++++--------- 9 files changed, 253 insertions(+), 201 deletions(-) diff --git a/usr/src/sys/miscfs/procfs/procfs.h b/usr/src/sys/miscfs/procfs/procfs.h index d325a66acd..45b617c8bc 100644 --- a/usr/src/sys/miscfs/procfs/procfs.h +++ b/usr/src/sys/miscfs/procfs/procfs.h @@ -8,7 +8,7 @@ * * %sccs.include.redist.c% * - * @(#)procfs.h 8.6 (Berkeley) %G% + * @(#)procfs.h 8.7 (Berkeley) %G% * * From: * $Id: procfs.h,v 3.2 1993/12/15 09:40:17 jsp Exp $ @@ -19,6 +19,7 @@ */ typedef enum { Proot, /* the filesystem root */ + Pcurproc, /* symbolic link for curproc */ Pproc, /* a process-specific sub-directory */ Pfile, /* the executable file */ Pmem, /* the process's memory image */ @@ -68,9 +69,9 @@ struct pfsdent { }; #define UIO_MX sizeof(struct pfsdent) #define PROCFS_FILENO(pid, type) \ - (((type) == Proot) ? \ - 2 : \ - ((((pid)+1) << 3) + ((int) (type)))) + (((type) < Pproc) ? \ + ((type) + 2) : \ + ((((pid)+1) << 4) + ((int) (type)))) /* * Convert between pfsnode vnode @@ -84,29 +85,34 @@ struct vfs_namemap { int nm_val; }; -extern int vfs_getuserstr __P((struct uio *, char *, int *)); -extern vfs_namemap_t *vfs_findname __P((vfs_namemap_t *, char *, int)); +int vfs_getuserstr __P((struct uio *, char *, int *)); +vfs_namemap_t *vfs_findname __P((vfs_namemap_t *, char *, int)); /* */ struct reg; struct fpreg; #define PFIND(pid) ((pid) ? pfind(pid) : &proc0) -extern int procfs_freevp __P((struct vnode *)); -extern int procfs_allocvp __P((struct mount *, struct vnode **, long, pfstype)); -extern struct vnode *procfs_findtextvp __P((struct proc *)); -extern int procfs_sstep __P((struct proc *)); -extern void procfs_fix_sstep __P((struct proc *)); -extern int procfs_read_regs __P((struct proc *, struct reg *)); -extern int procfs_write_regs __P((struct proc *, struct reg *)); -extern int procfs_read_fpregs __P((struct proc *, struct fpreg *)); -extern int procfs_write_fpregs __P((struct proc *, struct fpreg *)); -extern int procfs_donote __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); -extern int procfs_doregs __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); -extern int procfs_dofpregs __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); -extern int procfs_domem __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); -extern int procfs_doctl __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); -extern int procfs_dostatus __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); +int procfs_freevp __P((struct vnode *)); +int procfs_allocvp __P((struct mount *, struct vnode **, long, pfstype)); +struct vnode *procfs_findtextvp __P((struct proc *)); +int procfs_sstep __P((struct proc *, int)); +void procfs_fix_sstep __P((struct proc *)); +int procfs_read_regs __P((struct proc *, struct reg *)); +int procfs_write_regs __P((struct proc *, struct reg *)); +int procfs_read_fpregs __P((struct proc *, struct fpreg *)); +int procfs_write_fpregs __P((struct proc *, struct fpreg *)); +int procfs_donote __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); +int procfs_doregs __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); +int procfs_dofpregs __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); +int procfs_domem __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); +int procfs_doctl __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); +int procfs_dostatus __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); + +/* functions to check whether or not files should be displayed */ +int procfs_validfile __P((struct proc *)); +int procfs_validfpregs __P((struct proc *)); +int procfs_validregs __P((struct proc *)); #define PROCFS_LOCKED 0x01 #define PROCFS_WANT 0x02 @@ -141,7 +147,7 @@ int procfs_ioctl __P((struct vop_ioctl_args *)); #define procfs_rmdir ((int (*) __P((struct vop_rmdir_args *))) procfs_badop) #define procfs_symlink ((int (*) __P((struct vop_symlink_args *))) procfs_badop) int procfs_readdir __P((struct vop_readdir_args *)); -#define procfs_readlink ((int (*) __P((struct vop_readlink_args *))) procfs_badop) +int procfs_readlink __P((struct vop_readlink_args *)); int procfs_abortop __P((struct vop_abortop_args *)); int procfs_inactive __P((struct vop_inactive_args *)); int procfs_reclaim __P((struct vop_reclaim_args *)); diff --git a/usr/src/sys/miscfs/procfs/procfs_ctl.c b/usr/src/sys/miscfs/procfs/procfs_ctl.c index 11123e81e7..cce6ca6c1b 100644 --- a/usr/src/sys/miscfs/procfs/procfs_ctl.c +++ b/usr/src/sys/miscfs/procfs/procfs_ctl.c @@ -8,7 +8,7 @@ * * %sccs.include.redist.c% * - * @(#)procfs_ctl.c 8.3 (Berkeley) %G% + * @(#)procfs_ctl.c 8.4 (Berkeley) %G% * * From: * $Id: procfs_ctl.c,v 3.2 1993/12/15 09:40:17 jsp Exp $ @@ -24,8 +24,14 @@ #include #include #include +#include #include +#ifndef FIX_SSTEP +#define FIX_SSTEP(p) +#endif + + /* * True iff process (p) is in trace wait state * relative to process (curp) @@ -35,15 +41,6 @@ (p)->p_pptr == (curp) && \ ((p)->p_flag & P_TRACED)) -#ifdef notdef -#define FIX_SSTEP(p) { \ - procfs_fix_sstep(p); \ - } \ -} -#else -#define FIX_SSTEP(p) -#endif - #define PROCFS_CTL_ATTACH 1 #define PROCFS_CTL_DETACH 2 #define PROCFS_CTL_STEP 3 @@ -180,7 +177,8 @@ procfs_control(curp, p, op) * Step. Let the target process execute a single instruction. */ case PROCFS_CTL_STEP: - procfs_sstep(p); + if (error = procfs_sstep(p, 1)) + return (error); break; /* diff --git a/usr/src/sys/miscfs/procfs/procfs_fpregs.c b/usr/src/sys/miscfs/procfs/procfs_fpregs.c index bf9b015b6f..71e665c4f2 100644 --- a/usr/src/sys/miscfs/procfs/procfs_fpregs.c +++ b/usr/src/sys/miscfs/procfs/procfs_fpregs.c @@ -8,7 +8,7 @@ * * %sccs.include.redist.c% * - * @(#)procfs_fpregs.c 8.1 (Berkeley) %G% + * @(#)procfs_fpregs.c 8.2 (Berkeley) %G% * * From: * $Id: procfs_regs.c,v 3.2 1993/12/15 09:40:17 jsp Exp $ @@ -59,3 +59,11 @@ procfs_dofpregs(curp, p, pfs, uio) uio->uio_offset = 0; return (error); } + +int +procfs_validfpregs(p) + struct proc *p; +{ + + return ((p->p_flag & P_SYSTEM) == 0); +} diff --git a/usr/src/sys/miscfs/procfs/procfs_mem.c b/usr/src/sys/miscfs/procfs/procfs_mem.c index ff4ca33a5b..ef8f24c3bc 100644 --- a/usr/src/sys/miscfs/procfs/procfs_mem.c +++ b/usr/src/sys/miscfs/procfs/procfs_mem.c @@ -9,7 +9,7 @@ * * %sccs.include.redist.c% * - * @(#)procfs_mem.c 8.4 (Berkeley) %G% + * @(#)procfs_mem.c 8.5 (Berkeley) %G% * * From: * $Id: procfs_mem.c,v 3.2 1993/12/15 09:40:17 jsp Exp $ @@ -180,14 +180,11 @@ procfs_domem(curp, p, pfs, uio) struct pfsnode *pfs; struct uio *uio; { - int error; if (uio->uio_resid == 0) return (0); - error = procfs_rwmem(p, uio); - - return (error); + return (procfs_rwmem(p, uio)); } /* @@ -205,6 +202,7 @@ struct vnode * procfs_findtextvp(p) struct proc *p; { + return (p->p_textvp); } diff --git a/usr/src/sys/miscfs/procfs/procfs_regs.c b/usr/src/sys/miscfs/procfs/procfs_regs.c index 05a9657386..34847bcec9 100644 --- a/usr/src/sys/miscfs/procfs/procfs_regs.c +++ b/usr/src/sys/miscfs/procfs/procfs_regs.c @@ -8,7 +8,7 @@ * * %sccs.include.redist.c% * - * @(#)procfs_regs.c 8.3 (Berkeley) %G% + * @(#)procfs_regs.c 8.4 (Berkeley) %G% * * From: * $Id: procfs_regs.c,v 3.2 1993/12/15 09:40:17 jsp Exp $ @@ -59,3 +59,11 @@ procfs_doregs(curp, p, pfs, uio) uio->uio_offset = 0; return (error); } + +int +procfs_validregs(p) + struct proc *p; +{ + + return ((p->p_flag & P_SYSTEM) == 0); +} diff --git a/usr/src/sys/miscfs/procfs/procfs_status.c b/usr/src/sys/miscfs/procfs/procfs_status.c index b3ff0717eb..f204664dd3 100644 --- a/usr/src/sys/miscfs/procfs/procfs_status.c +++ b/usr/src/sys/miscfs/procfs/procfs_status.c @@ -8,7 +8,7 @@ * * %sccs.include.redist.c% * - * @(#)procfs_status.c 8.3 (Berkeley) %G% + * @(#)procfs_status.c 8.4 (Berkeley) %G% * * From: * $Id: procfs_status.c,v 3.1 1993/12/15 09:40:17 jsp Exp $ @@ -101,7 +101,7 @@ procfs_dostatus(curp, p, pfs, uio) cr = p->p_ucred; - ps += sprintf(ps, " %d", cr->cr_uid, cr->cr_gid); + ps += sprintf(ps, " %d", cr->cr_uid); for (i = 0; i < cr->cr_ngroups; i++) ps += sprintf(ps, ",%d", cr->cr_groups[i]); ps += sprintf(ps, "\n"); @@ -109,7 +109,7 @@ procfs_dostatus(curp, p, pfs, uio) xlen = ps - psbuf; xlen -= uio->uio_offset; ps = psbuf + uio->uio_offset; - xlen = min(xlen, uio->uio_resid); + xlen = imin(xlen, uio->uio_resid); if (xlen <= 0) error = 0; else diff --git a/usr/src/sys/miscfs/procfs/procfs_subr.c b/usr/src/sys/miscfs/procfs/procfs_subr.c index 9505f33ee5..6c4b989692 100644 --- a/usr/src/sys/miscfs/procfs/procfs_subr.c +++ b/usr/src/sys/miscfs/procfs/procfs_subr.c @@ -8,7 +8,7 @@ * * %sccs.include.redist.c% * - * @(#)procfs_subr.c 8.4 (Berkeley) %G% + * @(#)procfs_subr.c 8.5 (Berkeley) %G% * * From: * $Id: procfs_subr.c,v 3.2 1993/12/15 09:40:17 jsp Exp $ @@ -59,18 +59,20 @@ procfs_allocvp(mp, vpp, pid, pfs_type) long pid; pfstype pfs_type; { - int error; struct pfsnode *pfs; + struct vnode *vp; struct pfsnode **pp; + int error; loop: for (pfs = pfshead; pfs != 0; pfs = pfs->pfs_next) { + vp = PFSTOV(pfs); if (pfs->pfs_pid == pid && pfs->pfs_type == pfs_type && - PFSTOV(pfs)->v_mount == mp) { - if (vget(pfs->pfs_vnode, 0)) + vp->v_mount == mp) { + if (vget(vp, 0)) goto loop; - *vpp = pfs->pfs_vnode; + *vpp = vp; return (0); } } @@ -86,18 +88,17 @@ loop: } pfsvplock |= PROCFS_LOCKED; - error = getnewvnode(VT_PROCFS, mp, procfs_vnodeop_p, vpp); - if (error) + if (error = getnewvnode(VT_PROCFS, mp, procfs_vnodeop_p, vpp)) goto out; + vp = *vpp; - MALLOC((*vpp)->v_data, void *, sizeof(struct pfsnode), - M_TEMP, M_WAITOK); + MALLOC(pfs, void *, sizeof(struct pfsnode), M_TEMP, M_WAITOK); + vp->v_data = pfs; - pfs = VTOPFS(*vpp); pfs->pfs_next = 0; pfs->pfs_pid = (pid_t) pid; pfs->pfs_type = pfs_type; - pfs->pfs_vnode = *vpp; + pfs->pfs_vnode = vp; pfs->pfs_flags = 0; pfs->pfs_fileno = PROCFS_FILENO(pid, pfs_type); @@ -106,46 +107,44 @@ loop: pfs->pfs_mode = (VREAD|VEXEC) | (VREAD|VEXEC) >> 3 | (VREAD|VEXEC) >> 6; + vp->v_type = VDIR; + vp->v_flag = VROOT; + break; + + case Pcurproc: /* /proc/curproc = lr--r--r-- */ + pfs->pfs_mode = (VREAD) | + (VREAD >> 3) | + (VREAD >> 6); + vp->v_type = VLNK; break; case Pproc: pfs->pfs_mode = (VREAD|VEXEC) | (VREAD|VEXEC) >> 3 | (VREAD|VEXEC) >> 6; + vp->v_type = VDIR; break; case Pfile: - pfs->pfs_mode = (VREAD|VWRITE); - break; - case Pmem: - pfs->pfs_mode = (VREAD|VWRITE); - break; - case Pregs: - pfs->pfs_mode = (VREAD|VWRITE); - break; - case Pfpregs: pfs->pfs_mode = (VREAD|VWRITE); + vp->v_type = VREG; break; case Pctl: + case Pnote: + case Pnotepg: pfs->pfs_mode = (VWRITE); + vp->v_type = VREG; break; case Pstatus: pfs->pfs_mode = (VREAD) | (VREAD >> 3) | (VREAD >> 6); - break; - - case Pnote: - pfs->pfs_mode = (VWRITE); - break; - - case Pnotepg: - pfs->pfs_mode = (VWRITE); + vp->v_type = VREG; break; default: @@ -257,8 +256,7 @@ vfs_getuserstr(uio, buf, buflenp) return (EMSGSIZE); xlen = uio->uio_resid; - error = uiomove(buf, xlen, uio); - if (error) + if (error = uiomove(buf, xlen, uio)) return (error); /* allow multiple writes without seeks */ @@ -280,6 +278,7 @@ vfs_findname(nm, buf, buflen) char *buf; int buflen; { + for (; nm->nm_name; nm++) if (bcmp(buf, (char *) nm->nm_name, buflen+1) == 0) return (nm); diff --git a/usr/src/sys/miscfs/procfs/procfs_vfsops.c b/usr/src/sys/miscfs/procfs/procfs_vfsops.c index ea6b6d5cfe..c60f093eae 100644 --- a/usr/src/sys/miscfs/procfs/procfs_vfsops.c +++ b/usr/src/sys/miscfs/procfs/procfs_vfsops.c @@ -8,7 +8,7 @@ * * %sccs.include.redist.c% * - * @(#)procfs_vfsops.c 8.4 (Berkeley) %G% + * @(#)procfs_vfsops.c 8.5 (Berkeley) %G% * * From: * $Id: procfs_vfsops.c,v 3.1 1993/12/15 09:40:17 jsp Exp $ @@ -96,24 +96,10 @@ procfs_root(mp, vpp) struct mount *mp; struct vnode **vpp; { - struct pfsnode *pfs; - struct vnode *vp; - int error; - - error = procfs_allocvp(mp, &vp, (pid_t) 0, Proot); - if (error) - return (error); - vp->v_type = VDIR; - vp->v_flag = VROOT; - pfs = VTOPFS(vp); - - *vpp = vp; - return (0); + return (procfs_allocvp(mp, vpp, 0, Proot)); } -/* - */ /* ARGSUSED */ procfs_start(mp, flags, p) struct mount *mp; diff --git a/usr/src/sys/miscfs/procfs/procfs_vnops.c b/usr/src/sys/miscfs/procfs/procfs_vnops.c index 1d6a95d9c1..1294d34ddd 100644 --- a/usr/src/sys/miscfs/procfs/procfs_vnops.c +++ b/usr/src/sys/miscfs/procfs/procfs_vnops.c @@ -8,7 +8,7 @@ * * %sccs.include.redist.c% * - * @(#)procfs_vnops.c 8.7 (Berkeley) %G% + * @(#)procfs_vnops.c 8.8 (Berkeley) %G% * * From: * $Id: procfs_vnops.c,v 3.2 1993/12/15 09:40:17 jsp Exp $ @@ -29,8 +29,9 @@ #include #include #include -#include #include /* for PAGE_SIZE */ +#include +#include /* * Vnode Operations. @@ -43,20 +44,24 @@ * used in procfs_lookup and procfs_readdir */ static struct pfsnames { - u_short d_namlen; + u_char d_type; + u_char d_namlen; char d_name[PROCFS_NAMELEN]; pfstype d_pfstype; + int (*d_valid) __P((struct proc *p)); } procent[] = { #define N(s) sizeof(s)-1, s /* namlen, nam, type */ - { N("file"), Pfile }, - { N("mem"), Pmem }, - { N("regs"), Pregs }, - { N("fpregs"), Pfpregs }, - { N("ctl"), Pctl }, - { N("status"), Pstatus }, - { N("note"), Pnote }, - { N("notepg"), Pnotepg }, + { DT_DIR, N("."), Pproc, NULL }, + { DT_DIR, N(".."), Proot, NULL }, + { DT_REG, N("file"), Pfile, procfs_validfile }, + { DT_REG, N("mem"), Pmem, NULL }, + { DT_REG, N("regs"), Pregs, procfs_validregs }, + { DT_REG, N("fpregs"), Pfpregs, procfs_validfpregs }, + { DT_REG, N("ctl"), Pctl, NULL }, + { DT_REG, N("status"), Pstatus, NULL }, + { DT_REG, N("note"), Pnote, NULL }, + { DT_REG, N("notepg"), Pnotepg, NULL }, #undef N }; #define Nprocent (sizeof(procent)/sizeof(procent[0])) @@ -90,10 +95,9 @@ procfs_open(ap) return (ENOENT); /* was ESRCH, jsp */ if ((pfs->pfs_flags & FWRITE) && (ap->a_mode & O_EXCL) || - (pfs->pfs_flags & O_EXCL) && (ap->a_mode & FWRITE)) + (pfs->pfs_flags & O_EXCL) && (ap->a_mode & FWRITE)) return (EBUSY); - if (ap->a_mode & FWRITE) pfs->pfs_flags = ap->a_mode & (FWRITE|O_EXCL); @@ -218,10 +222,8 @@ procfs_reclaim(ap) struct vnode *a_vp; } */ *ap; { - int error; - error = procfs_freevp(ap->a_vp); - return (error); + return (procfs_freevp(ap->a_vp)); } /* @@ -272,9 +274,8 @@ procfs_print(ap) { struct pfsnode *pfs = VTOPFS(ap->a_vp); - printf("tag VT_PROCFS, pid %d, mode %x, flags %x\n", - pfs->pfs_pid, - pfs->pfs_mode, pfs->pfs_flags); + printf("tag VT_PROCFS, type %s, pid %d, mode %x, flags %x\n", + pfs->pfs_type, pfs->pfs_pid, pfs->pfs_mode, pfs->pfs_flags); } /* @@ -329,6 +330,7 @@ procfs_getattr(ap) /* first check the process still exists */ switch (pfs->pfs_type) { case Proot: + case Pcurproc: procp = 0; break; @@ -351,33 +353,43 @@ procfs_getattr(ap) vap->va_blocksize = PAGE_SIZE; vap->va_bytes = vap->va_size = 0; + /* + * Make all times be current TOD. + * It would be possible to get the process start + * time from the p_stat structure, but there's + * no "file creation" time stamp anyway, and the + * p_stat structure is not addressible if u. gets + * swapped out for that process. + * + * XXX + * Note that microtime() returns a timeval, not a timespec. + */ + microtime(&vap->va_ctime); + vap->va_atime = vap->va_mtime = vap->va_ctime; + /* * If the process has exercised some setuid or setgid * privilege, then rip away read/write permission so * that only root can gain access. */ switch (pfs->pfs_type) { + case Pmem: case Pregs: case Pfpregs: - case Pmem: if (procp->p_flag & P_SUGID) vap->va_mode &= ~((VREAD|VWRITE)| ((VREAD|VWRITE)>>3)| ((VREAD|VWRITE)>>6)); + case Pctl: + case Pstatus: + case Pnote: + case Pnotepg: + vap->va_nlink = 1; + vap->va_uid = procp->p_ucred->cr_uid; + vap->va_gid = procp->p_ucred->cr_gid; break; } - /* - * Make all times be current TOD. - * It would be possible to get the process start - * time from the p_stat structure, but there's - * no "file creation" time stamp anyway, and the - * p_stat structure is not addressible if u. gets - * swapped out for that process. - */ - microtime(&vap->va_ctime); - vap->va_atime = vap->va_mtime = vap->va_ctime; - /* * now do the object specific fields * @@ -390,15 +402,30 @@ procfs_getattr(ap) switch (pfs->pfs_type) { case Proot: - vap->va_nlink = 2; + /* + * Set nlink to 1 to tell fts(3) we don't actually know. + */ + vap->va_nlink = 1; + vap->va_uid = 0; + vap->va_gid = 0; + vap->va_size = vap->va_bytes = DEV_BSIZE; + break; + + case Pcurproc: { + char buf[16]; /* should be enough */ + vap->va_nlink = 1; vap->va_uid = 0; vap->va_gid = 0; + vap->va_size = vap->va_bytes = + sprintf(buf, "%ld", (long)curproc->p_pid); break; + } case Pproc: vap->va_nlink = 2; vap->va_uid = procp->p_ucred->cr_uid; vap->va_gid = procp->p_ucred->cr_gid; + vap->va_size = vap->va_bytes = DEV_BSIZE; break; case Pfile: @@ -406,24 +433,24 @@ procfs_getattr(ap) break; case Pmem: - vap->va_nlink = 1; vap->va_bytes = vap->va_size = ctob(procp->p_vmspace->vm_tsize + procp->p_vmspace->vm_dsize + procp->p_vmspace->vm_ssize); - vap->va_uid = procp->p_ucred->cr_uid; - vap->va_gid = procp->p_ucred->cr_gid; break; case Pregs: + vap->va_bytes = vap->va_size = sizeof(struct reg); + break; + case Pfpregs: + vap->va_bytes = vap->va_size = sizeof(struct fpreg); + break; + case Pctl: case Pstatus: case Pnote: case Pnotepg: - vap->va_nlink = 1; - vap->va_uid = procp->p_ucred->cr_uid; - vap->va_gid = procp->p_ucred->cr_gid; break; default: @@ -482,8 +509,9 @@ procfs_access(ap) * If you're the super-user, * you always get access. */ - if (ap->a_cred->cr_uid == (uid_t) 0) + if (ap->a_cred->cr_uid == 0) return (0); + vap = &vattr; if (error = VOP_GETATTR(ap->a_vp, vap, ap->a_cred, ap->a_p)) return (error); @@ -497,7 +525,7 @@ procfs_access(ap) gid_t *gp; int i; - (ap->a_mode) >>= 3; + ap->a_mode >>= 3; gp = ap->a_cred->cr_groups; for (i = 0; i < ap->a_cred->cr_ngroups; i++, gp++) if (vap->va_gid == *gp) @@ -557,9 +585,9 @@ procfs_lookup(ap) return (EIO); if (CNEQ(cnp, "curproc", 7)) - pid = cnp->cn_proc->p_pid; - else - pid = atopid(pname, cnp->cn_namelen); + return (procfs_allocvp(dvp->v_mount, vpp, 0, Pcurproc)); + + pid = atopid(pname, cnp->cn_namelen); if (pid == NO_PID) return (ENOENT); @@ -567,15 +595,7 @@ procfs_lookup(ap) if (procp == 0) return (ENOENT); - error = procfs_allocvp(dvp->v_mount, &nvp, pid, Pproc); - if (error) - return (error); - - nvp->v_type = VDIR; - pfs = VTOPFS(nvp); - - *vpp = nvp; - return (0); + return (procfs_allocvp(dvp->v_mount, vpp, pid, Pproc)); case Pproc: if (cnp->cn_flags & ISDOTDOT) { @@ -591,7 +611,8 @@ procfs_lookup(ap) struct pfsnames *dp = &procent[i]; if (cnp->cn_namelen == dp->d_namlen && - bcmp(pname, dp->d_name, dp->d_namlen) == 0) { + bcmp(pname, dp->d_name, dp->d_namlen) == 0 && + (dp->d_valid == NULL || (*dp->d_valid)(procp))) { pfs_type = dp->d_pfstype; goto found; } @@ -601,29 +622,30 @@ procfs_lookup(ap) found: if (pfs_type == Pfile) { nvp = procfs_findtextvp(procp); - if (nvp) { - VREF(nvp); - VOP_LOCK(nvp); - } else { - error = ENXIO; - } - } else { - error = procfs_allocvp(dvp->v_mount, &nvp, - pfs->pfs_pid, pfs_type); - if (error) - return (error); - - nvp->v_type = VREG; - pfs = VTOPFS(nvp); + if (nvp == NULLVP) + return (ENXIO); + VREF(nvp); + VOP_LOCK(nvp); + *vpp = nvp; + return (0); } - *vpp = nvp; - return (error); + + return (procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid, + pfs_type)); default: return (ENOTDIR); } } +int +procfs_validfile(p) + struct proc *p; +{ + + return (procfs_findtextvp(p) != NULLVP); +} + /* * readdir returns directory entries from pfsnode (vp). * @@ -681,24 +703,27 @@ procfs_readdir(ap) * from the procent[] table (top of this file). */ case Pproc: { - while (uio->uio_resid >= UIO_MX) { - struct pfsnames *dt; + pid_t pid = pfs->pfs_pid; + struct pfsnames *dt; + + for (dt = &procent[i]; i < Nprocent && uio->uio_resid >= UIO_MX; + dt++, i++) { + struct proc *p = PFIND(pid); - if (i >= Nprocent) + if (p == NULL) break; - dt = &procent[i]; + if (dt->d_valid && (*dt->d_valid)(p) == 0) + continue; dp->d_reclen = UIO_MX; - dp->d_fileno = PROCFS_FILENO(pfs->pfs_pid, dt->d_pfstype); - dp->d_type = DT_REG; + dp->d_fileno = PROCFS_FILENO(pid, dt->d_pfstype); dp->d_namlen = dt->d_namlen; - bcopy(dt->d_name, dp->d_name, sizeof(dt->d_name)-1); - error = uiomove((caddr_t) dp, UIO_MX, uio); - if (error) + bcopy(dt->d_name, dp->d_name, dt->d_namlen + 1); + dp->d_type = dt->d_type; + + if (error = uiomove((caddr_t)dp, UIO_MX, uio)) break; - count += UIO_MX; - i++; } break; @@ -715,55 +740,61 @@ procfs_readdir(ap) */ case Proot: { - int pcnt; #ifdef PROCFS_ZOMBIE int doingzomb = 0; #endif - volatile struct proc *p; - - p = allproc; - -#define PROCFS_XFILES 1 /* number of other entries, like "curproc" */ - pcnt = PROCFS_XFILES; + int pcnt = 0; + volatile struct proc *p = allproc; - while (p && uio->uio_resid >= UIO_MX) { + again: + for (; p && uio->uio_resid >= UIO_MX; i++, pcnt++) { bzero((char *) dp, UIO_MX); - dp->d_type = DT_DIR; dp->d_reclen = UIO_MX; switch (i) { - case 0: - /* ship out entry for "curproc" */ - dp->d_fileno = PROCFS_FILENO(PID_MAX+1, Pproc); - dp->d_namlen = sprintf(dp->d_name, "curproc"); + case 0: /* `.' */ + case 1: /* `..' */ + dp->d_fileno = PROCFS_FILENO(0, Proot); + dp->d_namlen = i + 1; + bcopy("..", dp->d_name, dp->d_namlen); + dp->d_name[i + 1] = '\0'; + dp->d_type = DT_DIR; + break; + + case 2: + dp->d_fileno = PROCFS_FILENO(0, Pcurproc); + dp->d_namlen = 7; + bcopy("curproc", dp->d_name, 8); + dp->d_type = DT_LNK; break; default: - if (pcnt >= i) { - dp->d_fileno = PROCFS_FILENO(p->p_pid, Pproc); - dp->d_namlen = sprintf(dp->d_name, "%ld", (long) p->p_pid); + while (pcnt < i) { + pcnt++; + p = p->p_next; + if (!p) + goto done; } - + dp->d_fileno = PROCFS_FILENO(p->p_pid, Pproc); + dp->d_namlen = sprintf(dp->d_name, "%ld", + (long)p->p_pid); + dp->d_type = DT_REG; p = p->p_next; - -#ifdef PROCFS_ZOMBIE - if (p == 0 && doingzomb == 0) { - doingzomb = 1; - p = zombproc; - } -#endif - - if (pcnt++ < i) - continue; - break; } - error = uiomove((caddr_t) dp, UIO_MX, uio); - if (error) + + if (error = uiomove((caddr_t)dp, UIO_MX, uio)) break; - count += UIO_MX; - i++; } + done: + +#ifdef PROCFS_ZOMBIE + if (p == 0 && doingzomb == 0) { + doingzomb = 1; + p = zombproc; + goto again; + } +#endif break; @@ -779,6 +810,24 @@ procfs_readdir(ap) return (error); } +/* + * readlink reads the link of `curproc' + */ +procfs_readlink(ap) + struct vop_readlink_args *ap; +{ + struct uio *uio = ap->a_uio; + char buf[16]; /* should be enough */ + int len; + + if (VTOPFS(ap->a_vp)->pfs_fileno != PROCFS_FILENO(0, Pcurproc)) + return (EINVAL); + + len = sprintf(buf, "%ld", (long)curproc->p_pid); + + return (uiomove((caddr_t)buf, len, ap->a_uio)); +} + /* * convert decimal ascii to pid_t */ -- 2.20.1