diff options
author | Patrick Mooney <pmooney@pfmooney.com> | 2016-12-16 16:01:40 -0800 |
---|---|---|
committer | Robert Mustacchi <rm@joyent.com> | 2016-12-29 15:56:00 -0800 |
commit | fee52838cd1191a3efe83b67de7bccdd401af35e (patch) | |
tree | a223064b1d3ff2b70822ecc53094058be19e5a2f /usr/src | |
parent | de48325308952b7883679d1687191f3ffe507b19 (diff) | |
download | illumos-gate-fee52838cd1191a3efe83b67de7bccdd401af35e.tar.gz |
7696 procfs lacks adequate access checks for CREAT actions
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Alex Wilson <alex.wilson@joyent.com>
Reviewed by: Dan McDonald <danmcd@omniti.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/common/fs/proc/prvnops.c | 46 |
1 files changed, 30 insertions, 16 deletions
diff --git a/usr/src/uts/common/fs/proc/prvnops.c b/usr/src/uts/common/fs/proc/prvnops.c index 7f017a0b08..6b78bae584 100644 --- a/usr/src/uts/common/fs/proc/prvnops.c +++ b/usr/src/uts/common/fs/proc/prvnops.c @@ -21,7 +21,7 @@ /* * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2014, Joyent, Inc. All rights reserved. + * Copyright 2016 Joyent, Inc. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ @@ -3428,21 +3428,34 @@ prcreate(vnode_t *dp, char *comp, vattr_t *vap, vcexcl_t excl, if ((error = prlookup(dp, comp, vpp, NULL, 0, NULL, cr, ct, NULL, NULL)) != 0) { - if (error == ENOENT) /* can't O_CREAT nonexistent files */ - error = EACCES; /* unwriteable directories */ - } else { - if (excl == EXCL) /* O_EXCL */ - error = EEXIST; - else if (vap->va_mask & AT_SIZE) { /* O_TRUNC */ + if (error == ENOENT) { + /* One can't O_CREAT nonexistent files in /proc. */ + error = EACCES; + } + return (error); + } + + if (excl == EXCL) { + /* Disallow the O_EXCL case */ + error = EEXIST; + } else if ((error = praccess(*vpp, mode, 0, cr, ct)) == 0) { + /* Before proceeding, handle O_TRUNC if necessary. */ + if (vap->va_mask & AT_SIZE) { vnode_t *vp = *vpp; - uint_t mask; - if (vp->v_type == VDIR) + if (vp->v_type == VDIR) { + /* Only allow O_TRUNC on files */ error = EISDIR; - else if (vp->v_type != VPROC || - VTOP(vp)->pr_type != PR_FD) + } else if (vp->v_type != VPROC || + VTOP(vp)->pr_type != PR_FD) { + /* + * Disallow for files outside of the + * /proc/<pid>/fd/<n> entries + */ error = EACCES; - else { /* /proc/<pid>/fd/<n> */ + } else { + uint_t mask; + vp = VTOP(vp)->pr_realvp; mask = vap->va_mask; vap->va_mask = AT_SIZE; @@ -3450,10 +3463,11 @@ prcreate(vnode_t *dp, char *comp, vattr_t *vap, vcexcl_t excl, vap->va_mask = mask; } } - if (error) { - VN_RELE(*vpp); - *vpp = NULL; - } + } + + if (error) { + VN_RELE(*vpp); + *vpp = NULL; } return (error); } |