summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Fiddaman <omnios@citrus-it.co.uk>2020-02-03 15:53:26 +0000
committerAndy Fiddaman <omnios@citrus-it.co.uk>2020-02-08 23:13:39 +0000
commit19ee9cd1f5161e227951200cab5ecbff45fd5d71 (patch)
treec194a665727a638313debbb8b699bcad8145dd48
parent52aec5b9758f6352670ab269980b437a987f4822 (diff)
downloadillumos-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.c27
-rw-r--r--usr/src/uts/common/fs/proc/prvnops.c114
-rw-r--r--usr/src/uts/common/sys/prsystm.h2
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 *);