diff options
author | Andy Fiddaman <omnios@citrus-it.co.uk> | 2020-02-03 15:53:26 +0000 |
---|---|---|
committer | Andy Fiddaman <omnios@citrus-it.co.uk> | 2020-02-08 23:13:39 +0000 |
commit | 19ee9cd1f5161e227951200cab5ecbff45fd5d71 (patch) | |
tree | c194a665727a638313debbb8b699bcad8145dd48 | |
parent | 52aec5b9758f6352670ab269980b437a987f4822 (diff) | |
download | illumos-joyent-19ee9cd1f5161e227951200cab5ecbff45fd5d71.tar.gz |
12277 /proc/<PID>/fdinfo should resolve paths relative to current process
Reviewed by: John Levon <john.levon@joyent.com>
Reviewed by: Jason King <jason.king@joyent.com>
Approved by: Dan McDonald <danmcd@joyent.com>
-rw-r--r-- | usr/src/uts/common/fs/proc/prsubr.c | 27 | ||||
-rw-r--r-- | usr/src/uts/common/fs/proc/prvnops.c | 114 | ||||
-rw-r--r-- | usr/src/uts/common/sys/prsystm.h | 2 |
3 files changed, 73 insertions, 70 deletions
diff --git a/usr/src/uts/common/fs/proc/prsubr.c b/usr/src/uts/common/fs/proc/prsubr.c index ff6ba06d5b..fdb823d7ba 100644 --- a/usr/src/uts/common/fs/proc/prsubr.c +++ b/usr/src/uts/common/fs/proc/prsubr.c @@ -2505,24 +2505,16 @@ static size_t prfdinfopath(proc_t *p, vnode_t *vp, list_t *data, cred_t *cred) { char *pathname; - vnode_t *vrootp; size_t pathlen; size_t sz = 0; pathlen = MAXPATHLEN + 1; pathname = kmem_alloc(pathlen, KM_SLEEP); - mutex_enter(&p->p_lock); - if ((vrootp = PTOU(p)->u_rdir) == NULL) - vrootp = rootdir; - VN_HOLD(vrootp); - mutex_exit(&p->p_lock); - - if (vnodetopath(vrootp, vp, pathname, pathlen, cred) == 0) { + if (vnodetopath(NULL, vp, pathname, pathlen, cred) == 0) { sz += prfdinfomisc(data, PR_PATHNAME, pathname, strlen(pathname) + 1); } - VN_RELE(vrootp); kmem_free(pathname, pathlen); return (sz); @@ -2781,7 +2773,7 @@ prgetfdinfosize(proc_t *p, vnode_t *vp, cred_t *cred) int prgetfdinfo(proc_t *p, vnode_t *vp, prfdinfo_t *fdinfo, cred_t *cred, - list_t *data) + cred_t *file_cred, list_t *data) { vattr_t vattr; int error; @@ -2808,9 +2800,20 @@ prgetfdinfo(proc_t *p, vnode_t *vp, prfdinfo_t *fdinfo, cred_t *cred, VOP_SEEK(vp, 0, (offset_t *)&fdinfo->pr_offset, NULL) != 0) fdinfo->pr_offset = -1; - /* Attributes */ + /* + * Attributes + * + * We have two cred_t structures available here. + * 'cred' is the caller's credential, and 'file_cred' is the credential + * for the file being inspected. + * + * When looking up the file attributes, file_cred is used in order + * that the correct ownership is set for doors and FIFOs. Since the + * caller has permission to read the fdinfo file in proc, this does + * not expose any additional information. + */ vattr.va_mask = AT_STAT; - if (VOP_GETATTR(vp, &vattr, 0, cred, NULL) == 0) { + if (VOP_GETATTR(vp, &vattr, 0, file_cred, NULL) == 0) { fdinfo->pr_major = getmajor(vattr.va_fsid); fdinfo->pr_minor = getminor(vattr.va_fsid); fdinfo->pr_rmajor = getmajor(vattr.va_rdev); diff --git a/usr/src/uts/common/fs/proc/prvnops.c b/usr/src/uts/common/fs/proc/prvnops.c index a324181683..3bde19f837 100644 --- a/usr/src/uts/common/fs/proc/prvnops.c +++ b/usr/src/uts/common/fs/proc/prvnops.c @@ -661,7 +661,7 @@ static int (*pr_read_function[PR_NFILES])() = { /* ARGSUSED */ static int -pr_read_inval(prnode_t *pnp, uio_t *uiop) +pr_read_inval(prnode_t *pnp, uio_t *uiop, cred_t *cr) { /* * No read() on any /proc directory, use getdents(2) instead. @@ -724,7 +724,7 @@ pr_read_as(prnode_t *pnp, uio_t *uiop) } static int -pr_read_status(prnode_t *pnp, uio_t *uiop) +pr_read_status(prnode_t *pnp, uio_t *uiop, cred_t *cr) { pstatus_t *sp; int error; @@ -746,7 +746,7 @@ pr_read_status(prnode_t *pnp, uio_t *uiop) } static int -pr_read_lstatus(prnode_t *pnp, uio_t *uiop) +pr_read_lstatus(prnode_t *pnp, uio_t *uiop, cred_t *cr) { proc_t *p; kthread_t *t; @@ -792,7 +792,7 @@ pr_read_lstatus(prnode_t *pnp, uio_t *uiop) } static int -pr_read_psinfo(prnode_t *pnp, uio_t *uiop) +pr_read_psinfo(prnode_t *pnp, uio_t *uiop, cred_t *cr) { psinfo_t psinfo; proc_t *p; @@ -819,7 +819,7 @@ pr_read_psinfo(prnode_t *pnp, uio_t *uiop) } static int -pr_read_fdinfo(prnode_t *pnp, uio_t *uiop) +pr_read_fdinfo(prnode_t *pnp, uio_t *uiop, cred_t *cr) { prfdinfo_t *fdinfo; list_t data; @@ -827,7 +827,7 @@ pr_read_fdinfo(prnode_t *pnp, uio_t *uiop) vnode_t *vp; uint_t fd; file_t *fp; - cred_t *cred; + cred_t *file_cred; short ufp_flag; int error = 0; @@ -882,8 +882,8 @@ pr_read_fdinfo(prnode_t *pnp, uio_t *uiop) if ((fdinfo->pr_fileflags & (FSEARCH | FEXEC)) == 0) fdinfo->pr_fileflags += FOPEN; fdinfo->pr_offset = fp->f_offset; - cred = fp->f_cred; - crhold(cred); + file_cred = fp->f_cred; + crhold(file_cred); /* * Information from the vnode (rather than the file_t) is retrieved * later, in prgetfdinfo() - for example sock_getfasync() @@ -892,9 +892,9 @@ pr_read_fdinfo(prnode_t *pnp, uio_t *uiop) prunlock(pnp); - error = prgetfdinfo(p, vp, fdinfo, cred, &data); + error = prgetfdinfo(p, vp, fdinfo, cr, file_cred, &data); - crfree(cred); + crfree(file_cred); VN_RELE(vp); @@ -908,7 +908,7 @@ out: } static int -pr_read_lpsinfo(prnode_t *pnp, uio_t *uiop) +pr_read_lpsinfo(prnode_t *pnp, uio_t *uiop, cred_t *cr) { proc_t *p; kthread_t *t; @@ -1022,28 +1022,28 @@ readmap_common: } static int -pr_read_map(prnode_t *pnp, uio_t *uiop) +pr_read_map(prnode_t *pnp, uio_t *uiop, cred_t *cr) { ASSERT(pnp->pr_type == PR_MAP); return (pr_read_map_common(pnp, uiop, pnp->pr_type)); } static int -pr_read_rmap(prnode_t *pnp, uio_t *uiop) +pr_read_rmap(prnode_t *pnp, uio_t *uiop, cred_t *cr) { ASSERT(pnp->pr_type == PR_RMAP); return (pr_read_map_common(pnp, uiop, pnp->pr_type)); } static int -pr_read_xmap(prnode_t *pnp, uio_t *uiop) +pr_read_xmap(prnode_t *pnp, uio_t *uiop, cred_t *cr) { ASSERT(pnp->pr_type == PR_XMAP); return (pr_read_map_common(pnp, uiop, pnp->pr_type)); } static int -pr_read_cred(prnode_t *pnp, uio_t *uiop) +pr_read_cred(prnode_t *pnp, uio_t *uiop, cred_t *cr) { proc_t *p; prcred_t *pcrp; @@ -1078,7 +1078,7 @@ out: } static int -pr_read_priv(prnode_t *pnp, uio_t *uiop) +pr_read_priv(prnode_t *pnp, uio_t *uiop, cred_t *cr) { proc_t *p; size_t psize = prgetprivsize(); @@ -1102,7 +1102,7 @@ out: } static int -pr_read_sigact(prnode_t *pnp, uio_t *uiop) +pr_read_sigact(prnode_t *pnp, uio_t *uiop, cred_t *cr) { int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG; proc_t *p; @@ -1141,7 +1141,7 @@ out: } static int -pr_read_auxv(prnode_t *pnp, uio_t *uiop) +pr_read_auxv(prnode_t *pnp, uio_t *uiop, cred_t *cr) { auxv_t auxv[__KERN_NAUXV_IMPL]; proc_t *p; @@ -1176,7 +1176,7 @@ pr_read_auxv(prnode_t *pnp, uio_t *uiop) * For now let's just have a ldt of size 0 for 64-bit processes. */ static int -pr_read_ldt(prnode_t *pnp, uio_t *uiop) +pr_read_ldt(prnode_t *pnp, uio_t *uiop, cred_t *cr) { proc_t *p; struct ssd *ssd; @@ -1212,7 +1212,7 @@ pr_read_ldt(prnode_t *pnp, uio_t *uiop) #endif /* __x86 */ static int -pr_read_usage(prnode_t *pnp, uio_t *uiop) +pr_read_usage(prnode_t *pnp, uio_t *uiop, cred_t *cr) { prhusage_t *pup; prusage_t *upup; @@ -1301,7 +1301,7 @@ out: } static int -pr_read_lusage(prnode_t *pnp, uio_t *uiop) +pr_read_lusage(prnode_t *pnp, uio_t *uiop, cred_t *cr) { int nlwp; prhusage_t *pup; @@ -1412,7 +1412,7 @@ pr_read_lusage(prnode_t *pnp, uio_t *uiop) } static int -pr_read_pagedata(prnode_t *pnp, uio_t *uiop) +pr_read_pagedata(prnode_t *pnp, uio_t *uiop, cred_t *cr) { proc_t *p; int error; @@ -1437,7 +1437,7 @@ pr_read_pagedata(prnode_t *pnp, uio_t *uiop) } static int -pr_read_opagedata(prnode_t *pnp, uio_t *uiop) +pr_read_opagedata(prnode_t *pnp, uio_t *uiop, cred_t *cr) { proc_t *p; struct as *as; @@ -1464,7 +1464,7 @@ pr_read_opagedata(prnode_t *pnp, uio_t *uiop) } static int -pr_read_watch(prnode_t *pnp, uio_t *uiop) +pr_read_watch(prnode_t *pnp, uio_t *uiop, cred_t *cr) { proc_t *p; int error; @@ -1510,7 +1510,7 @@ pr_read_watch(prnode_t *pnp, uio_t *uiop) } static int -pr_read_lwpstatus(prnode_t *pnp, uio_t *uiop) +pr_read_lwpstatus(prnode_t *pnp, uio_t *uiop, cred_t *cr) { lwpstatus_t *sp; int error; @@ -1541,7 +1541,7 @@ out: } static int -pr_read_lwpsinfo(prnode_t *pnp, uio_t *uiop) +pr_read_lwpsinfo(prnode_t *pnp, uio_t *uiop, cred_t *cr) { lwpsinfo_t lwpsinfo; proc_t *p; @@ -1588,7 +1588,7 @@ pr_read_lwpsinfo(prnode_t *pnp, uio_t *uiop) } static int -pr_read_lwpusage(prnode_t *pnp, uio_t *uiop) +pr_read_lwpusage(prnode_t *pnp, uio_t *uiop, cred_t *cr) { prhusage_t *pup; prusage_t *upup; @@ -1639,7 +1639,7 @@ out: } static int -pr_read_lwpname(prnode_t *pnp, uio_t *uiop) +pr_read_lwpname(prnode_t *pnp, uio_t *uiop, cred_t *cr) { char lwpname[THREAD_NAME_MAX]; kthread_t *t; @@ -1667,7 +1667,7 @@ pr_read_lwpname(prnode_t *pnp, uio_t *uiop) /* ARGSUSED */ static int -pr_read_xregs(prnode_t *pnp, uio_t *uiop) +pr_read_xregs(prnode_t *pnp, uio_t *uiop, cred_t *cr) { #if defined(__sparc) proc_t *p; @@ -1708,7 +1708,7 @@ out: } static int -pr_read_spymaster(prnode_t *pnp, uio_t *uiop) +pr_read_spymaster(prnode_t *pnp, uio_t *uiop, cred_t *cr) { psinfo_t psinfo; int error; @@ -1738,7 +1738,7 @@ pr_read_spymaster(prnode_t *pnp, uio_t *uiop) } static int -pr_read_secflags(prnode_t *pnp, uio_t *uiop) +pr_read_secflags(prnode_t *pnp, uio_t *uiop, cred_t *cr) { prsecflags_t ret; int error; @@ -1759,7 +1759,7 @@ pr_read_secflags(prnode_t *pnp, uio_t *uiop) #if defined(__sparc) static int -pr_read_gwindows(prnode_t *pnp, uio_t *uiop) +pr_read_gwindows(prnode_t *pnp, uio_t *uiop, cred_t *cr) { proc_t *p; kthread_t *t; @@ -1803,7 +1803,7 @@ out: /* ARGSUSED */ static int -pr_read_asrs(prnode_t *pnp, uio_t *uiop) +pr_read_asrs(prnode_t *pnp, uio_t *uiop, cred_t *cr) { int error; @@ -1840,7 +1840,7 @@ pr_read_asrs(prnode_t *pnp, uio_t *uiop) #endif /* __sparc */ static int -pr_read_piddir(prnode_t *pnp, uio_t *uiop) +pr_read_piddir(prnode_t *pnp, uio_t *uiop, cred_t *cr) { ASSERT(pnp->pr_type == PR_PIDDIR); ASSERT(pnp->pr_pidfile != NULL); @@ -1853,7 +1853,7 @@ pr_read_piddir(prnode_t *pnp, uio_t *uiop) } static int -pr_read_pidfile(prnode_t *pnp, uio_t *uiop) +pr_read_pidfile(prnode_t *pnp, uio_t *uiop, cred_t *cr) { int error; @@ -1961,7 +1961,7 @@ static int (*pr_read_function_32[PR_NFILES])() = { }; static int -pr_read_status_32(prnode_t *pnp, uio_t *uiop) +pr_read_status_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) { pstatus32_t *sp; proc_t *p; @@ -1995,7 +1995,7 @@ pr_read_status_32(prnode_t *pnp, uio_t *uiop) } static int -pr_read_lstatus_32(prnode_t *pnp, uio_t *uiop) +pr_read_lstatus_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) { proc_t *p; kthread_t *t; @@ -2049,7 +2049,7 @@ pr_read_lstatus_32(prnode_t *pnp, uio_t *uiop) } static int -pr_read_psinfo_32(prnode_t *pnp, uio_t *uiop) +pr_read_psinfo_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) { psinfo32_t psinfo; proc_t *p; @@ -2076,7 +2076,7 @@ pr_read_psinfo_32(prnode_t *pnp, uio_t *uiop) } static int -pr_read_lpsinfo_32(prnode_t *pnp, uio_t *uiop) +pr_read_lpsinfo_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) { proc_t *p; kthread_t *t; @@ -2192,28 +2192,28 @@ readmap32_common: } static int -pr_read_map_32(prnode_t *pnp, uio_t *uiop) +pr_read_map_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) { ASSERT(pnp->pr_type == PR_MAP); return (pr_read_map_common_32(pnp, uiop, pnp->pr_type)); } static int -pr_read_rmap_32(prnode_t *pnp, uio_t *uiop) +pr_read_rmap_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) { ASSERT(pnp->pr_type == PR_RMAP); return (pr_read_map_common_32(pnp, uiop, pnp->pr_type)); } static int -pr_read_xmap_32(prnode_t *pnp, uio_t *uiop) +pr_read_xmap_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) { ASSERT(pnp->pr_type == PR_XMAP); return (pr_read_map_common_32(pnp, uiop, pnp->pr_type)); } static int -pr_read_sigact_32(prnode_t *pnp, uio_t *uiop) +pr_read_sigact_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) { int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG; proc_t *p; @@ -2257,7 +2257,7 @@ out: } static int -pr_read_auxv_32(prnode_t *pnp, uio_t *uiop) +pr_read_auxv_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) { auxv32_t auxv[__KERN_NAUXV_IMPL]; proc_t *p; @@ -2292,7 +2292,7 @@ pr_read_auxv_32(prnode_t *pnp, uio_t *uiop) } static int -pr_read_usage_32(prnode_t *pnp, uio_t *uiop) +pr_read_usage_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) { prhusage_t *pup; prusage32_t *upup; @@ -2381,7 +2381,7 @@ out: } static int -pr_read_lusage_32(prnode_t *pnp, uio_t *uiop) +pr_read_lusage_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) { int nlwp; prhusage_t *pup; @@ -2493,7 +2493,7 @@ pr_read_lusage_32(prnode_t *pnp, uio_t *uiop) } static int -pr_read_pagedata_32(prnode_t *pnp, uio_t *uiop) +pr_read_pagedata_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) { proc_t *p; int error; @@ -2523,7 +2523,7 @@ pr_read_pagedata_32(prnode_t *pnp, uio_t *uiop) } static int -pr_read_opagedata_32(prnode_t *pnp, uio_t *uiop) +pr_read_opagedata_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) { proc_t *p; struct as *as; @@ -2556,7 +2556,7 @@ pr_read_opagedata_32(prnode_t *pnp, uio_t *uiop) } static int -pr_read_watch_32(prnode_t *pnp, uio_t *uiop) +pr_read_watch_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) { proc_t *p; int error; @@ -2606,7 +2606,7 @@ pr_read_watch_32(prnode_t *pnp, uio_t *uiop) } static int -pr_read_lwpstatus_32(prnode_t *pnp, uio_t *uiop) +pr_read_lwpstatus_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) { lwpstatus32_t *sp; proc_t *p; @@ -2649,7 +2649,7 @@ out: } static int -pr_read_lwpsinfo_32(prnode_t *pnp, uio_t *uiop) +pr_read_lwpsinfo_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) { lwpsinfo32_t lwpsinfo; proc_t *p; @@ -2694,7 +2694,7 @@ pr_read_lwpsinfo_32(prnode_t *pnp, uio_t *uiop) } static int -pr_read_lwpusage_32(prnode_t *pnp, uio_t *uiop) +pr_read_lwpusage_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) { prhusage_t *pup; prusage32_t *upup; @@ -2745,7 +2745,7 @@ out: } static int -pr_read_spymaster_32(prnode_t *pnp, uio_t *uiop) +pr_read_spymaster_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) { psinfo32_t psinfo; int error; @@ -2776,7 +2776,7 @@ pr_read_spymaster_32(prnode_t *pnp, uio_t *uiop) #if defined(__sparc) static int -pr_read_gwindows_32(prnode_t *pnp, uio_t *uiop) +pr_read_gwindows_32(prnode_t *pnp, uio_t *uiop, cred_t *cr) { proc_t *p; kthread_t *t; @@ -2842,11 +2842,11 @@ prread(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr, caller_context_t *ct) * data. An ILP32 process will see ILP32 data. */ if (curproc->p_model == DATAMODEL_LP64) - return (pr_read_function[pnp->pr_type](pnp, uiop)); + return (pr_read_function[pnp->pr_type](pnp, uiop, cr)); else - return (pr_read_function_32[pnp->pr_type](pnp, uiop)); + return (pr_read_function_32[pnp->pr_type](pnp, uiop, cr)); #else - return (pr_read_function[pnp->pr_type](pnp, uiop)); + return (pr_read_function[pnp->pr_type](pnp, uiop, cr)); #endif } diff --git a/usr/src/uts/common/sys/prsystm.h b/usr/src/uts/common/sys/prsystm.h index 9aa047740a..4b71191818 100644 --- a/usr/src/uts/common/sys/prsystm.h +++ b/usr/src/uts/common/sys/prsystm.h @@ -86,7 +86,7 @@ extern void prgetsecflags(proc_t *, struct prsecflags *); extern int prnsegs(struct as *, int); extern u_offset_t prgetfdinfosize(proc_t *, vnode_t *, cred_t *); extern int prgetfdinfo(proc_t *, vnode_t *, struct prfdinfo *, cred_t *, - list_t *); + cred_t *, list_t *); extern void prexit(proc_t *); extern void prfree(proc_t *); extern void prlwpexit(kthread_t *); |