summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_extattr.c
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2002-08-01 15:37:12 +0000
committerrwatson <rwatson@FreeBSD.org>2002-08-01 15:37:12 +0000
commit7af111191c599878545a46db61bc2ce941a6db99 (patch)
tree2623052f2ac865b58a0c903ad64a3abea0b1b692 /sys/kern/vfs_extattr.c
parent788a8001cc095577779652d0f77dddb2739e4bf6 (diff)
downloadFreeBSD-src-7af111191c599878545a46db61bc2ce941a6db99.zip
FreeBSD-src-7af111191c599878545a46db61bc2ce941a6db99.tar.gz
Introduce support for Mandatory Access Control and extensible
kernel access control. Invoke appropriate MAC entry points to authorize the following operations: truncate on open() (write) access() (access) readlink() (readlink) chflags(), lchflags(), fchflags() (setflag) chmod(), fchmod(), lchmod() (setmode) chown(), fchown(), lchown() (setowner) utimes(), lutimes(), futimes() (setutimes) truncate(), ftrunfcate() (write) revoke() (revoke) fhopen() (open) truncate on fhopen() (write) extattr_set_fd, extattr_set_file() (setextattr) extattr_get_fd, extattr_get_file() (getextattr) extattr_delete_fd(), extattr_delete_file() (setextattr) These entry points permit MAC policies to enforce a variety of protections on vnodes. More vnode checks to come, especially in non-native ABIs. Obtained from: TrustedBSD Project Sponsored by: DARPA, NAI Labs
Diffstat (limited to 'sys/kern/vfs_extattr.c')
-rw-r--r--sys/kern/vfs_extattr.c105
1 files changed, 95 insertions, 10 deletions
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c
index bf43908..8d4c9b4 100644
--- a/sys/kern/vfs_extattr.c
+++ b/sys/kern/vfs_extattr.c
@@ -733,7 +733,12 @@ open(td, uap)
VATTR_NULL(&vat);
vat.va_size = 0;
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
- error = VOP_SETATTR(vp, &vat, td->td_ucred, td);
+#ifdef MAC
+ error = mac_check_vnode_op(td->td_ucred, vp,
+ MAC_OP_VNODE_WRITE);
+ if (error == 0)
+#endif
+ error = VOP_SETATTR(vp, &vat, td->td_ucred, td);
VOP_UNLOCK(vp, 0, td);
vn_finished_write(mp);
if (error)
@@ -1305,6 +1310,11 @@ vn_access(vp, user_flags, cred, td)
flags |= VWRITE;
if (user_flags & X_OK)
flags |= VEXEC;
+#ifdef MAC
+ error = mac_check_vnode_access(cred, vp, flags);
+ if (error)
+ return (error);
+#endif
if ((flags & VWRITE) == 0 || (error = vn_writechk(vp)) == 0)
error = VOP_ACCESS(vp, flags, cred, td);
}
@@ -1746,6 +1756,13 @@ readlink(td, uap)
return (error);
NDFREE(&nd, NDF_ONLY_PNBUF);
vp = nd.ni_vp;
+#ifdef MAC
+ error = mac_check_vnode_readlink(td->td_ucred, vp);
+ if (error) {
+ vput(vp);
+ return (error);
+ }
+#endif
if (vp->v_type != VLNK)
error = EINVAL;
else {
@@ -1794,9 +1811,16 @@ setfflags(td, vp, flags)
return (error);
VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
- VATTR_NULL(&vattr);
- vattr.va_flags = flags;
- error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
+#ifdef MAC
+ error = mac_check_vnode_setflags(td->td_ucred, vp, vattr.va_flags);
+ if (error == 0) {
+#endif
+ VATTR_NULL(&vattr);
+ vattr.va_flags = flags;
+ error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
+#ifdef MAC
+ }
+#endif
VOP_UNLOCK(vp, 0, td);
vn_finished_write(mp);
return (error);
@@ -1902,7 +1926,11 @@ setfmode(td, vp, mode)
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
VATTR_NULL(&vattr);
vattr.va_mode = mode & ALLPERMS;
- error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
+#ifdef MAC
+ error = mac_check_vnode_setmode(td->td_ucred, vp, vattr.va_mode);
+ if (error == 0)
+#endif
+ error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
VOP_UNLOCK(vp, 0, td);
vn_finished_write(mp);
return error;
@@ -2019,7 +2047,12 @@ setfown(td, vp, uid, gid)
VATTR_NULL(&vattr);
vattr.va_uid = uid;
vattr.va_gid = gid;
- error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
+#ifdef MAC
+ error = mac_check_vnode_setowner(td->td_ucred, vp, vattr.va_uid,
+ vattr.va_gid);
+ if (error == 0)
+#endif
+ error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
VOP_UNLOCK(vp, 0, td);
vn_finished_write(mp);
return error;
@@ -2178,7 +2211,12 @@ setutimes(td, vp, ts, numtimes, nullflag)
vattr.va_birthtime = ts[2];
if (nullflag)
vattr.va_vaflags |= VA_UTIMES_NULL;
- error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
+#ifdef MAC
+ error = mac_check_vnode_setutimes(td->td_ucred, vp, vattr.va_atime,
+ vattr.va_mtime);
+ if (error == 0)
+#endif
+ error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
VOP_UNLOCK(vp, 0, td);
vn_finished_write(mp);
return error;
@@ -2328,6 +2366,10 @@ truncate(td, uap)
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
if (vp->v_type == VDIR)
error = EISDIR;
+#ifdef MAC
+ else if ((error = mac_check_vnode_op(td->td_ucred, vp,
+ MAC_OP_VNODE_WRITE))) {}
+#endif
else if ((error = vn_writechk(vp)) == 0 &&
(error = VOP_ACCESS(vp, VWRITE, td->td_ucred, td)) == 0) {
VATTR_NULL(&vattr);
@@ -2382,6 +2424,10 @@ ftruncate(td, uap)
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
if (vp->v_type == VDIR)
error = EISDIR;
+#ifdef MAC
+ else if ((error = mac_check_vnode_op(td->td_ucred, vp,
+ MAC_OP_VNODE_WRITE))) {}
+#endif
else if ((error = vn_writechk(vp)) == 0) {
VATTR_NULL(&vattr);
vattr.va_size = SCARG(uap, length);
@@ -3073,6 +3119,13 @@ revoke(td, uap)
vput(vp);
return (EINVAL);
}
+#ifdef MAC
+ error = mac_check_vnode_revoke(td->td_ucred, vp);
+ if (error) {
+ vput(vp);
+ return (error);
+ }
+#endif
error = VOP_GETATTR(vp, &vattr, td->td_ucred, td);
if (error) {
vput(vp);
@@ -3257,6 +3310,11 @@ fhopen(td, uap)
mode |= VREAD;
if (fmode & O_APPEND)
mode |= VAPPEND;
+#ifdef MAC
+ error = mac_check_vnode_open(td->td_ucred, vp, mode);
+ if (error)
+ goto bad;
+#endif
if (mode) {
error = VOP_ACCESS(vp, mode, td->td_ucred, td);
if (error)
@@ -3270,9 +3328,17 @@ fhopen(td, uap)
}
VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); /* XXX */
- VATTR_NULL(vap);
- vap->va_size = 0;
- error = VOP_SETATTR(vp, vap, td->td_ucred, td);
+#ifdef MAC
+ error = mac_check_vnode_op(td->td_ucred, vp,
+ MAC_OP_VNODE_WRITE);
+ if (error == 0) {
+#endif
+ VATTR_NULL(vap);
+ vap->va_size = 0;
+ error = VOP_SETATTR(vp, vap, td->td_ucred, td);
+#ifdef MAC
+ }
+#endif
vn_finished_write(mp);
if (error)
goto bad;
@@ -3584,6 +3650,13 @@ extattr_set_vp(struct vnode *vp, int attrnamespace, const char *attrname,
auio.uio_td = td;
cnt = nbytes;
+#ifdef MAC
+ error = mac_check_vnode_setextattr(td->td_ucred, vp, attrnamespace,
+ attrname, &auio);
+ if (error)
+ goto done;
+#endif
+
error = VOP_SETEXTATTR(vp, attrnamespace, attrname, &auio,
td->td_ucred, td);
cnt -= auio.uio_resid;
@@ -3704,6 +3777,13 @@ extattr_get_vp(struct vnode *vp, int attrnamespace, const char *attrname,
} else
sizep = &size;
+#ifdef MAC
+ error = mac_check_vnode_getextattr(td->td_ucred, vp, attrnamespace,
+ attrname, &auio);
+ if (error)
+ goto done;
+#endif
+
error = VOP_GETEXTATTR(vp, attrnamespace, attrname, auiop, sizep,
td->td_ucred, td);
@@ -3800,6 +3880,11 @@ extattr_delete_vp(struct vnode *vp, int attrnamespace, const char *attrname,
VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
+#ifdef MAC
+ error = mac_check_vnode_setextattr(td->td_ucred, vp, attrnamespace,
+ attrname, NULL);
+#endif
+
error = VOP_SETEXTATTR(vp, attrnamespace, attrname, NULL, td->td_ucred,
td);
OpenPOWER on IntegriCloud