summaryrefslogtreecommitdiffstats
path: root/sys/nfs
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>1997-05-09 13:18:42 +0000
committerdfr <dfr@FreeBSD.org>1997-05-09 13:18:42 +0000
commitab4272e09ecd5d3838b564026ac4cbdb411fec35 (patch)
treefe82f1c42b7455f1d4701351ca1a2b8a529ac19c /sys/nfs
parent5a3da545f6ed278467b68b3b902c0fa8fcd113a1 (diff)
downloadFreeBSD-src-ab4272e09ecd5d3838b564026ac4cbdb411fec35.zip
FreeBSD-src-ab4272e09ecd5d3838b564026ac4cbdb411fec35.tar.gz
Prevent a mapped root which appears on the server as e.g. nobody from
accessing files which it shouldn't be able to. This required a better approximation of VOP_ACCESS for NFSv2 (NFSv3 already has an ACCESS rpc which is a better solution) and adding a call to VOP_ACCESS from VOP_LOOKUP. PR: kern/876, kern/2635 Submitted by: David Malone <dwmalone@maths.tcd.ie> (for kern/2635)
Diffstat (limited to 'sys/nfs')
-rw-r--r--sys/nfs/nfs_vnops.c50
1 files changed, 47 insertions, 3 deletions
diff --git a/sys/nfs/nfs_vnops.c b/sys/nfs/nfs_vnops.c
index 72a7a04..a498820 100644
--- a/sys/nfs/nfs_vnops.c
+++ b/sys/nfs/nfs_vnops.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95
- * $Id: nfs_vnops.c,v 1.46 1997/04/04 17:49:33 dfr Exp $
+ * $Id: nfs_vnops.c,v 1.47 1997/05/04 09:17:36 phk Exp $
*/
@@ -410,8 +410,49 @@ nfs_access(ap)
}
nfsm_reqdone;
return (error);
- } else
- return (nfsspec_access(ap));
+ } else {
+ if (error = nfsspec_access(ap))
+ return (error);
+
+ /*
+ * Attempt to prevent a mapped root from accessing a file
+ * which it shouldn't. We try to read a byte from the file
+ * if the user is root and the file is not zero length.
+ * After calling nfsspec_access, we should have the correct
+ * file size cached.
+ */
+ if (ap->a_cred->cr_uid == 0 && (ap->a_mode & VREAD)
+ && VTONFS(vp)->n_size > 0) {
+ struct iovec aiov;
+ struct uio auio;
+ char buf[1];
+
+ aiov.iov_base = buf;
+ aiov.iov_len = 1;
+ auio.uio_iov = &aiov;
+ auio.uio_iovcnt = 1;
+ auio.uio_offset = 0;
+ auio.uio_resid = 1;
+ auio.uio_segflg = UIO_SYSSPACE;
+ auio.uio_rw = UIO_READ;
+ auio.uio_procp = ap->a_p;
+
+ if (vp->v_type == VREG)
+ error = nfs_readrpc(vp, &auio, ap->a_cred);
+ else if (vp->v_type == VDIR) {
+ char* buf;
+ buf = malloc(NFS_DIRBLKSIZ, M_TEMP, M_WAITOK);
+ aiov.iov_base = buf;
+ aiov.iov_len = auio.uio_resid = NFS_DIRBLKSIZ;
+ error = nfs_readdirrpc(vp, &auio, ap->a_cred);
+ free(buf, M_TEMP);
+ } else if (vp->v_type = VLNK)
+ error = nfs_readlinkrpc(vp, &auio, ap->a_cred);
+ else
+ error = EACCES;
+ }
+ return (error);
+ }
}
/*
@@ -834,6 +875,9 @@ nfs_lookup(ap)
struct vattr vattr;
int vpid;
+ if (error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, p))
+ return (error);
+
newvp = *vpp;
vpid = newvp->v_id;
/*
OpenPOWER on IntegriCloud