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)
This commit is contained in:
parent
7a95f810ec
commit
a973eeb2c1
@ -34,7 +34,7 @@
|
|||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95
|
* @(#)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;
|
nfsm_reqdone;
|
||||||
return (error);
|
return (error);
|
||||||
} else
|
} else {
|
||||||
return (nfsspec_access(ap));
|
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;
|
struct vattr vattr;
|
||||||
int vpid;
|
int vpid;
|
||||||
|
|
||||||
|
if (error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, p))
|
||||||
|
return (error);
|
||||||
|
|
||||||
newvp = *vpp;
|
newvp = *vpp;
|
||||||
vpid = newvp->v_id;
|
vpid = newvp->v_id;
|
||||||
/*
|
/*
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95
|
* @(#)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;
|
nfsm_reqdone;
|
||||||
return (error);
|
return (error);
|
||||||
} else
|
} else {
|
||||||
return (nfsspec_access(ap));
|
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;
|
struct vattr vattr;
|
||||||
int vpid;
|
int vpid;
|
||||||
|
|
||||||
|
if (error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, p))
|
||||||
|
return (error);
|
||||||
|
|
||||||
newvp = *vpp;
|
newvp = *vpp;
|
||||||
vpid = newvp->v_id;
|
vpid = newvp->v_id;
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user