From owner-freebsd-current Tue May 6 06:14:31 1997 Return-Path: Received: (from root@localhost) by hub.freebsd.org (8.8.5/8.8.5) id GAA09489 for current-outgoing; Tue, 6 May 1997 06:14:31 -0700 (PDT) Received: from nlsystems.com (nlsys.demon.co.uk [158.152.125.33]) by hub.freebsd.org (8.8.5/8.8.5) with ESMTP id GAA09483 for ; Tue, 6 May 1997 06:14:23 -0700 (PDT) Received: from herring.nlsystems.com (herring.nlsystems.com [10.0.0.2]) by nlsystems.com (8.8.5/8.8.5) with SMTP id OAA22785; Tue, 6 May 1997 14:14:49 +0100 (BST) Date: Tue, 6 May 1997 14:14:49 +0100 (BST) From: Doug Rabson 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: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-current@freebsd.org X-Loop: FreeBSD.org Precedence: bulk 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