summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorPatrick Mooney <pmooney@pfmooney.com>2016-12-16 16:01:40 -0800
committerRobert Mustacchi <rm@joyent.com>2016-12-29 15:56:00 -0800
commitfee52838cd1191a3efe83b67de7bccdd401af35e (patch)
treea223064b1d3ff2b70822ecc53094058be19e5a2f /usr/src
parentde48325308952b7883679d1687191f3ffe507b19 (diff)
downloadillumos-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.c46
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);
}