diff options
author | rwatson <rwatson@FreeBSD.org> | 2003-01-31 21:13:25 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2003-01-31 21:13:25 +0000 |
commit | e9e0de5ca49975c9cdbde8a3c003ba0e84e31847 (patch) | |
tree | aa07cf9ac7cda19b1fe705000bbe8793af52d5c0 /sys | |
parent | 9dd70473b6bcaa295c57599a605acdb94ba8ef9c (diff) | |
download | FreeBSD-src-e9e0de5ca49975c9cdbde8a3c003ba0e84e31847.zip FreeBSD-src-e9e0de5ca49975c9cdbde8a3c003ba0e84e31847.tar.gz |
Correct handling of locking for chroot() and chdir() cases: rather
than having change_dir() release the vnode lock on success, hold the
lock so that we can use it later when invoking MAC checks and
VOP_ACCESS() in the chroot() code. Update the comment to reflect
this calling convention. Update callers to unlock the vnode
lock. Correct a typo regarding vnode naming in the MAC case that
crept in via the previous patch applied.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/vfs_extattr.c | 15 | ||||
-rw-r--r-- | sys/kern/vfs_syscalls.c | 15 |
2 files changed, 16 insertions, 14 deletions
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index 3752f0c..b78d545 100644 --- a/sys/kern/vfs_extattr.c +++ b/sys/kern/vfs_extattr.c @@ -465,6 +465,7 @@ kern_chdir(struct thread *td, char *path, enum uio_seg pathseg) NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, pathseg, path, td); if ((error = change_dir(&nd, td)) != 0) return (error); + VOP_UNLOCK(nd.ni_vp, 0, td); NDFREE(&nd, NDF_ONLY_PNBUF); FILEDESC_LOCK(fdp); vp = fdp->fd_cdir; @@ -543,10 +544,11 @@ chroot(td, uap) goto error; #ifdef MAC if ((error = mac_check_vnode_chroot(td->td_ucred, nd.ni_vp))) { - vput(vp); + vput(nd.ni_vp); goto error; } #endif + VOP_UNLOCK(nd.ni_vp, 0, td); FILEDESC_LOCK(fdp); if (chroot_allow_open_directories == 0 || (chroot_allow_open_directories == 1 && fdp->fd_rdir != rootvnode)) { @@ -574,7 +576,8 @@ error: } /* - * Common routine for chroot and chdir. + * Common routine for chroot and chdir. On success, the directory vnode + * is returned locked, and must be unlocked by the caller. */ static int change_dir(ndp, td) @@ -591,15 +594,13 @@ change_dir(ndp, td) if (vp->v_type != VDIR) error = ENOTDIR; #ifdef MAC - else if ((error = mac_check_vnode_chdir(td->td_ucred, vp)) != 0) { - } + if (error == 0) + error = mac_check_vnode_chdir(td->td_ucred, vp); #endif - else + if (error == 0) error = VOP_ACCESS(vp, VEXEC, td->td_ucred, td); if (error) vput(vp); - else - VOP_UNLOCK(vp, 0, td); return (error); } diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 3752f0c..b78d545 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -465,6 +465,7 @@ kern_chdir(struct thread *td, char *path, enum uio_seg pathseg) NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, pathseg, path, td); if ((error = change_dir(&nd, td)) != 0) return (error); + VOP_UNLOCK(nd.ni_vp, 0, td); NDFREE(&nd, NDF_ONLY_PNBUF); FILEDESC_LOCK(fdp); vp = fdp->fd_cdir; @@ -543,10 +544,11 @@ chroot(td, uap) goto error; #ifdef MAC if ((error = mac_check_vnode_chroot(td->td_ucred, nd.ni_vp))) { - vput(vp); + vput(nd.ni_vp); goto error; } #endif + VOP_UNLOCK(nd.ni_vp, 0, td); FILEDESC_LOCK(fdp); if (chroot_allow_open_directories == 0 || (chroot_allow_open_directories == 1 && fdp->fd_rdir != rootvnode)) { @@ -574,7 +576,8 @@ error: } /* - * Common routine for chroot and chdir. + * Common routine for chroot and chdir. On success, the directory vnode + * is returned locked, and must be unlocked by the caller. */ static int change_dir(ndp, td) @@ -591,15 +594,13 @@ change_dir(ndp, td) if (vp->v_type != VDIR) error = ENOTDIR; #ifdef MAC - else if ((error = mac_check_vnode_chdir(td->td_ucred, vp)) != 0) { - } + if (error == 0) + error = mac_check_vnode_chdir(td->td_ucred, vp); #endif - else + if (error == 0) error = VOP_ACCESS(vp, VEXEC, td->td_ucred, td); if (error) vput(vp); - else - VOP_UNLOCK(vp, 0, td); return (error); } |