diff options
author | rwatson <rwatson@FreeBSD.org> | 2002-10-19 20:25:57 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2002-10-19 20:25:57 +0000 |
commit | 91dee1ecbba5ea622c64fab5844ae12e871dbe97 (patch) | |
tree | a907ef280f27564bf96cb19f043b54b16b91dc53 | |
parent | 0a95b481d9addb0e2747448d170e885145510807 (diff) | |
download | FreeBSD-src-91dee1ecbba5ea622c64fab5844ae12e871dbe97.zip FreeBSD-src-91dee1ecbba5ea622c64fab5844ae12e871dbe97.tar.gz |
Hook up most of the MAC entry points relating to file/directory/node
creation, deletion, and rename. There are one or two other stray
cases I'll catch in follow-up commits (such as unix domain socket
creation); this permits MAC policy modules to limit the ability to
perform these operations based on existing UNIX credential / vnode
attributes, extended attributes, and security labels. In the rename
case using MAC, we now have to lock the from directory and file
vnodes for the MAC check, but this is done only in the MAC case,
and the locks are immediately released so that the remainder of the
rename implementation remains the same. Because the create check
takes a vattr to know object type information, we now initialize
additional fields in the VATTR passed to VOP_SYMLINK() in the MAC
case.
Approved by: re
Obtained from: TrustedBSD Project
Sponsored by: DARPA, Network Associates Laboratories
-rw-r--r-- | sys/kern/vfs_extattr.c | 70 | ||||
-rw-r--r-- | sys/kern/vfs_syscalls.c | 70 |
2 files changed, 136 insertions, 4 deletions
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index 27ab1c4..6e2aa6b 100644 --- a/sys/kern/vfs_extattr.c +++ b/sys/kern/vfs_extattr.c @@ -897,6 +897,11 @@ restart: return (error); goto restart; } +#ifdef MAC + if (error == 0 && !whiteout) + error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp, + &nd.ni_cnd, &vattr); +#endif if (!error) { VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); if (whiteout) @@ -969,10 +974,19 @@ restart: FILEDESC_LOCK(td->td_proc->p_fd); vattr.va_mode = (mode & ALLPERMS) & ~td->td_proc->p_fd->fd_cmask; FILEDESC_UNLOCK(td->td_proc->p_fd); +#ifdef MAC + error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, + &vattr); + if (error) + goto out; +#endif VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); if (error == 0) vput(nd.ni_vp); +#ifdef MAC +out: +#endif NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); vn_finished_write(mp); @@ -1111,11 +1125,21 @@ restart: FILEDESC_LOCK(td->td_proc->p_fd); vattr.va_mode = ACCESSPERMS &~ td->td_proc->p_fd->fd_cmask; FILEDESC_UNLOCK(td->td_proc->p_fd); +#ifdef MAC + vattr.va_type = VLNK; + error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, + &vattr); + if (error) + goto out2; +#endif VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, syspath); - NDFREE(&nd, NDF_ONLY_PNBUF); if (error == 0) vput(nd.ni_vp); +#ifdef MAC +out2: +#endif + NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); vn_finished_write(mp); ASSERT_VOP_UNLOCKED(nd.ni_dvp, "symlink"); @@ -1231,8 +1255,17 @@ restart: return (error); goto restart; } +#ifdef MAC + error = mac_check_vnode_delete(td->td_ucred, nd.ni_dvp, vp, + &nd.ni_cnd); + if (error) + goto out; +#endif VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); error = VOP_REMOVE(nd.ni_dvp, vp, &nd.ni_cnd); +#ifdef MAC +out: +#endif vn_finished_write(mp); } NDFREE(&nd, NDF_ONLY_PNBUF); @@ -2715,11 +2748,24 @@ kern_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg) int error; bwillwrite(); +#ifdef MAC + NDINIT(&fromnd, DELETE, LOCKPARENT | LOCKLEAF | SAVESTART, pathseg, + from, td); +#else NDINIT(&fromnd, DELETE, WANTPARENT | SAVESTART, pathseg, from, td); +#endif if ((error = namei(&fromnd)) != 0) return (error); +#ifdef MAC + error = mac_check_vnode_rename_from(td->td_ucred, fromnd.ni_dvp, + fromnd.ni_vp, &fromnd.ni_cnd); + VOP_UNLOCK(fromnd.ni_dvp, 0, td); + VOP_UNLOCK(fromnd.ni_vp, 0, td); +#endif fvp = fromnd.ni_vp; - if ((error = vn_start_write(fvp, &mp, V_WAIT | PCATCH)) != 0) { + if (error == 0) + error = vn_start_write(fvp, &mp, V_WAIT | PCATCH); + if (error != 0) { NDFREE(&fromnd, NDF_ONLY_PNBUF); vrele(fromnd.ni_dvp); vrele(fvp); @@ -2757,6 +2803,11 @@ kern_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg) */ if (fvp == tvp) error = -1; +#ifdef MAC + else + error = mac_check_vnode_rename_to(td->td_ucred, tdvp, + tond.ni_vp, fromnd.ni_dvp == tdvp, &tond.ni_cnd); +#endif out: if (!error) { VOP_LEASE(tdvp, td, td->td_ucred, LEASE_WRITE); @@ -2860,8 +2911,17 @@ restart: FILEDESC_LOCK(td->td_proc->p_fd); vattr.va_mode = (mode & ACCESSPERMS) &~ td->td_proc->p_fd->fd_cmask; FILEDESC_UNLOCK(td->td_proc->p_fd); +#ifdef MAC + error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, + &vattr); + if (error) + goto out; +#endif VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); +#ifdef MAC +out: +#endif NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); if (!error) @@ -2924,6 +2984,12 @@ restart: error = EBUSY; goto out; } +#ifdef MAC + error = mac_check_vnode_delete(td->td_ucred, nd.ni_dvp, vp, + &nd.ni_cnd); + if (error) + goto out; +#endif if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { NDFREE(&nd, NDF_ONLY_PNBUF); if (nd.ni_dvp == vp) diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 27ab1c4..6e2aa6b 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -897,6 +897,11 @@ restart: return (error); goto restart; } +#ifdef MAC + if (error == 0 && !whiteout) + error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp, + &nd.ni_cnd, &vattr); +#endif if (!error) { VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); if (whiteout) @@ -969,10 +974,19 @@ restart: FILEDESC_LOCK(td->td_proc->p_fd); vattr.va_mode = (mode & ALLPERMS) & ~td->td_proc->p_fd->fd_cmask; FILEDESC_UNLOCK(td->td_proc->p_fd); +#ifdef MAC + error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, + &vattr); + if (error) + goto out; +#endif VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); if (error == 0) vput(nd.ni_vp); +#ifdef MAC +out: +#endif NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); vn_finished_write(mp); @@ -1111,11 +1125,21 @@ restart: FILEDESC_LOCK(td->td_proc->p_fd); vattr.va_mode = ACCESSPERMS &~ td->td_proc->p_fd->fd_cmask; FILEDESC_UNLOCK(td->td_proc->p_fd); +#ifdef MAC + vattr.va_type = VLNK; + error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, + &vattr); + if (error) + goto out2; +#endif VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, syspath); - NDFREE(&nd, NDF_ONLY_PNBUF); if (error == 0) vput(nd.ni_vp); +#ifdef MAC +out2: +#endif + NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); vn_finished_write(mp); ASSERT_VOP_UNLOCKED(nd.ni_dvp, "symlink"); @@ -1231,8 +1255,17 @@ restart: return (error); goto restart; } +#ifdef MAC + error = mac_check_vnode_delete(td->td_ucred, nd.ni_dvp, vp, + &nd.ni_cnd); + if (error) + goto out; +#endif VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); error = VOP_REMOVE(nd.ni_dvp, vp, &nd.ni_cnd); +#ifdef MAC +out: +#endif vn_finished_write(mp); } NDFREE(&nd, NDF_ONLY_PNBUF); @@ -2715,11 +2748,24 @@ kern_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg) int error; bwillwrite(); +#ifdef MAC + NDINIT(&fromnd, DELETE, LOCKPARENT | LOCKLEAF | SAVESTART, pathseg, + from, td); +#else NDINIT(&fromnd, DELETE, WANTPARENT | SAVESTART, pathseg, from, td); +#endif if ((error = namei(&fromnd)) != 0) return (error); +#ifdef MAC + error = mac_check_vnode_rename_from(td->td_ucred, fromnd.ni_dvp, + fromnd.ni_vp, &fromnd.ni_cnd); + VOP_UNLOCK(fromnd.ni_dvp, 0, td); + VOP_UNLOCK(fromnd.ni_vp, 0, td); +#endif fvp = fromnd.ni_vp; - if ((error = vn_start_write(fvp, &mp, V_WAIT | PCATCH)) != 0) { + if (error == 0) + error = vn_start_write(fvp, &mp, V_WAIT | PCATCH); + if (error != 0) { NDFREE(&fromnd, NDF_ONLY_PNBUF); vrele(fromnd.ni_dvp); vrele(fvp); @@ -2757,6 +2803,11 @@ kern_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg) */ if (fvp == tvp) error = -1; +#ifdef MAC + else + error = mac_check_vnode_rename_to(td->td_ucred, tdvp, + tond.ni_vp, fromnd.ni_dvp == tdvp, &tond.ni_cnd); +#endif out: if (!error) { VOP_LEASE(tdvp, td, td->td_ucred, LEASE_WRITE); @@ -2860,8 +2911,17 @@ restart: FILEDESC_LOCK(td->td_proc->p_fd); vattr.va_mode = (mode & ACCESSPERMS) &~ td->td_proc->p_fd->fd_cmask; FILEDESC_UNLOCK(td->td_proc->p_fd); +#ifdef MAC + error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, + &vattr); + if (error) + goto out; +#endif VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); +#ifdef MAC +out: +#endif NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); if (!error) @@ -2924,6 +2984,12 @@ restart: error = EBUSY; goto out; } +#ifdef MAC + error = mac_check_vnode_delete(td->td_ucred, nd.ni_dvp, vp, + &nd.ni_cnd); + if (error) + goto out; +#endif if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { NDFREE(&nd, NDF_ONLY_PNBUF); if (nd.ni_dvp == vp) |