Date: Tue, 6 May 1997 14:14:49 +0100 (BST) From: Doug Rabson <dfr@nlsystems.com> To: dwmalone@maths.tcd.ie, simonm@solander.dcs.gla.ac.uk Cc: current@freebsd.org Subject: Fix for NFS bogusly accessing cached data Message-ID: <Pine.BSF.3.95q.970506140830.331K-100000@herring.nlsystems.com>
next in thread | raw e-mail | index | archive | help
Could someone review these fixes for kern/876 and kern/2635. Since NFSv2
does not have an ACCESS rpc, I have to attempt an uncached read of the
file to approximate a VREAD access check. This should cope with the
mapped root->nobody case in NFSv2. NFSv3 already fixed kern/876 since it
has a working ACCESS rpc.
The only part of this which worries me is that for directories I have to
read the first NFS_DIRBLKSIZ bytes of the directory (a limitation of
nfs_readdirrpc). Since this is only done for root and only for v2, I
think the overhead is ok.
Index: nfs_vnops.c
===================================================================
RCS file: /home/ncvs/src/sys/nfs/nfs_vnops.c,v
retrieving revision 1.47
diff -u -r1.47 nfs_vnops.c
--- nfs_vnops.c 1997/05/04 09:17:36 1.47
+++ nfs_vnops.c 1997/05/06 13:06:35
@@ -410,8 +410,49 @@
}
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);
+ }
}
/*
@@ -833,6 +874,9 @@
if ((error = cache_lookup(dvp, vpp, cnp)) && error != ENOENT) {
struct vattr vattr;
int vpid;
+
+ if (error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, p))
+ return (error);
newvp = *vpp;
vpid = newvp->v_id;
--
Doug Rabson Mail: dfr@nlsystems.com
Nonlinear Systems Ltd. Phone: +44 181 951 1891
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.3.95q.970506140830.331K-100000>
