Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 23 Jul 2002 14:46:49 -0700 (PDT)
From:      Robert Watson <rwatson@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 14791 for review
Message-ID:  <200207232146.g6NLknBV059031@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://people.freebsd.org/~peter/p4db/chv.cgi?CH=14791

Change 14791 by rwatson@rwatson_tislabs on 2002/07/23 14:46:35

	First pass at implementing access control checks for vnode read,
	write, and poll operations using a mac_cred_check_vnode_op()
	interface.  It may be it makes sense simply to move them to
	their own entry points, but it's not yet entirely clear.  This
	implementation is modeled on amigus's pipe access control
	checks.  No policy implementations yet: caution, if you enable
	this in policies without meaning to, a fair amount of
	suffering is to be had (revocation of tty access, etc).

Affected files ...

.. //depot/projects/trustedbsd/mac/sys/kern/kern_ktrace.c#9 edit
.. //depot/projects/trustedbsd/mac/sys/kern/kern_mac.c#190 edit
.. //depot/projects/trustedbsd/mac/sys/kern/tty_tty.c#5 edit
.. //depot/projects/trustedbsd/mac/sys/kern/vfs_syscalls.c#61 edit
.. //depot/projects/trustedbsd/mac/sys/kern/vfs_vnops.c#26 edit
.. //depot/projects/trustedbsd/mac/sys/sys/mac.h#120 edit
.. //depot/projects/trustedbsd/mac/sys/sys/mac_policy.h#85 edit

Differences ...

==== //depot/projects/trustedbsd/mac/sys/kern/kern_ktrace.c#9 (text+ko) ====

@@ -769,9 +769,10 @@
 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
 	(void)VOP_LEASE(vp, td, cred, LEASE_WRITE);
 #ifdef MAC
-	/* XXXMAC: Write authorization checks here. */
+	error = mac_cred_check_vnode_op(cred, vp, MAC_OP_VNODE_WRITE);
+	if (error == 0)
 #endif
-	error = VOP_WRITE(vp, &auio, IO_UNIT | IO_APPEND, cred);
+		error = VOP_WRITE(vp, &auio, IO_UNIT | IO_APPEND, cred);
 	if (error == 0 && uio != NULL) {
 		(void)VOP_LEASE(vp, td, cred, LEASE_WRITE);
 		error = VOP_WRITE(vp, uio, IO_UNIT | IO_APPEND, cred);

==== //depot/projects/trustedbsd/mac/sys/kern/kern_mac.c#190 (text+ko) ====

@@ -782,6 +782,10 @@
 			mpc->mpc_ops->mpo_cred_check_vnode_mmap_perms =
 			    mpe->mpe_function;
 			break;
+		case MAC_CRED_CHECK_VNODE_OP:
+			mpc->mpc_ops->mpo_cred_check_vnode_op =
+			    mpe->mpe_function;
+			break;
 		case MAC_IFNET_CHECK_SEND_MBUF:
 			mpc->mpc_ops->mpo_ifnet_check_send_mbuf =
 			    mpe->mpe_function;
@@ -2567,6 +2571,26 @@
 
 	return (error);
 }
+
+int
+mac_cred_check_vnode_op(struct ucred *cred, struct vnode *vp, int op)
+{
+	int error;
+
+	if (!mac_enforce_fs)
+		return (0);
+
+	ASSERT_VOP_LOCKED(vp, "mac_cred_check_vnode_op");
+
+	error = vn_refreshlabel(vp, cred);
+	if (error)
+		return (error);
+
+	MAC_CHECK(cred_check_vnode_op, cred, vp, &vp->v_label, op);
+
+	return (error);
+}
+
 int
 mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
     struct mac *extmac)

==== //depot/projects/trustedbsd/mac/sys/kern/tty_tty.c#5 (text+ko) ====

@@ -160,9 +160,12 @@
 		return (error);
 	vn_lock(ttyvp, LK_EXCLUSIVE | LK_RETRY, td);
 #ifdef MAC
-	/* XXXMAC: Write authorization check here. */
+	/* XXX: shouldn't the cred below be td->td_ucred not NOCRED? */
+	error = mac_cred_check_vnode_op(td->td_ucred, ttyvp,
+	    MAC_OP_VNODE_WRITE);
+	if (error == 0)
 #endif
-	error = VOP_WRITE(ttyvp, uio, flag, NOCRED);
+		error = VOP_WRITE(ttyvp, uio, flag, NOCRED);
 	VOP_UNLOCK(ttyvp, 0, td);
 	vn_finished_write(mp);
 	return (error);
@@ -204,6 +207,7 @@
 	}
 #ifdef MAC
 	/* XXXMAC: Ioctl authorization check here. */
+	/* XXX: Should this be td->td_ucred below? */
 #endif
 	return (VOP_IOCTL(ttyvp, cmd, addr, flag, NOCRED, td));
 }
@@ -216,6 +220,7 @@
 	struct thread *td;
 {
 	struct vnode *ttyvp;
+	int error;
 
 	PROC_LOCK(td->td_proc);
 	SESS_LOCK(td->td_proc->p_session);
@@ -227,7 +232,12 @@
 		/* try operation to get EOF/failure */
 		return (seltrue(dev, events, td));
 #ifdef MAC
-	/* XXXMAC: Poll authorization check here. */
+	vn_lock(ttyvp, LK_EXCLUSIVE | LK_RETRY, td);
+	error = mac_cred_check_vnode_op(td->td_ucred, ttyvp,
+	    MAC_OP_VNODE_POLL);
+	VOP_UNLOCK(ttyvp, 0, td);
+	if (error)
+		return (error);
 #endif
 	return (VOP_POLL(ttyvp, events, td->td_ucred, td));
 }

==== //depot/projects/trustedbsd/mac/sys/kern/vfs_syscalls.c#61 (text+ko) ====

@@ -1801,9 +1801,11 @@
 		vat.va_size = 0;
 		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
 #ifdef MAC
-		/* XXXMAC: Truncation check here. */
+		error = mac_cred_check_vnode_op(td->td_ucred, vp,
+		    MAC_OP_VNODE_WRITE);
+		if (error == 0)
 #endif
-		error = VOP_SETATTR(vp, &vat, td->td_ucred, td);
+			error = VOP_SETATTR(vp, &vat, td->td_ucred, td);
 		VOP_UNLOCK(vp, 0, td);
 		vn_finished_write(mp);
 		if (error)
@@ -3469,13 +3471,8 @@
 	if (vp->v_type == VDIR)
 		error = EISDIR;
 #ifdef MAC
-	/*
-	 * XXXMAC: Temporarily, use the 'open' check, although eventually
-	 * the 'write' check will be used.
-	 */
-	else if ((error = mac_cred_check_open_vnode(td->td_ucred, vp, VWRITE))
-	    != 0) {
-	}
+	else if ((error = mac_cred_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) {
@@ -4492,7 +4489,12 @@
 		VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
 		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);	/* XXX */
 #ifdef MAC
-		/* XXXMAC: Truncation check here. */
+		error = mac_cred_check_vnode_op(td->td_ucred, vp,
+		    MAC_OP_VNODE_WRITE);
+		if (error) {
+			vn_finished_write(mp);
+			goto bad;
+		}
 #endif
 		VATTR_NULL(vap);
 		vap->va_size = 0;

==== //depot/projects/trustedbsd/mac/sys/kern/vfs_vnops.c#26 (text+ko) ====

@@ -398,14 +398,16 @@
 	auio.uio_td = td;
 	if (rw == UIO_READ) {
 #ifdef MAC
-		/* XXXMAC: Read authorization check here. */
+		error = mac_cred_check_vnode_op(cred, vp, MAC_OP_VNODE_READ);
+		if (error == 0)
 #endif
-		error = VOP_READ(vp, &auio, ioflg, cred);
+			error = VOP_READ(vp, &auio, ioflg, cred);
 	} else {
 #ifdef MAC
-		/* XXXMAC: Write authorization check here. */
+		error = mac_cred_check_vnode_op(cred, vp, MAC_OP_VNODE_WRITE);
+		if (error == 0)
 #endif
-		error = VOP_WRITE(vp, &auio, ioflg, cred);
+			error = VOP_WRITE(vp, &auio, ioflg, cred);
 	}
 	if (aresid)
 		*aresid = auio.uio_resid;
@@ -493,9 +495,10 @@
 	ioflag |= sequential_heuristic(uio, fp);
 
 #ifdef MAC
-	/* XXXMAC: Read authorization check here. */
+	error = mac_cred_check_vnode_op(cred, vp, MAC_OP_VNODE_READ);
+	if (error == 0)
 #endif
-	error = VOP_READ(vp, uio, ioflag, cred);
+		error = VOP_READ(vp, uio, ioflag, cred);
 	if ((flags & FOF_OFFSET) == 0)
 		fp->f_offset = uio->uio_offset;
 	fp->f_nextoff = uio->uio_offset;
@@ -547,9 +550,10 @@
 		uio->uio_offset = fp->f_offset;
 	ioflag |= sequential_heuristic(uio, fp);
 #ifdef MAC
-	/* XXXMAC: Write authorization check here. */
+	error = mac_cred_check_vnode_op(cred, vp, MAC_OP_VNODE_WRITE);
+	if (error == 0)
 #endif
-	error = VOP_WRITE(vp, uio, ioflag, cred);
+		error = VOP_WRITE(vp, uio, ioflag, cred);
 	if ((flags & FOF_OFFSET) == 0)
 		fp->f_offset = uio->uio_offset;
 	fp->f_nextoff = uio->uio_offset;
@@ -779,12 +783,17 @@
 	struct ucred *cred;
 	struct thread *td;
 {
+	struct vnode *vp;
+	int error;
 
+	vp = (struct vnode *)fp->f_data;
 #ifdef MAC
-	/* XXXMAC: Poll authorization check here. */
+	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
+	error = mac_cred_check_vnode_op(cred, vp, MAC_OP_VNODE_POLL);
+	if (error)
+		return (error);
 #endif
-
-	return (VOP_POLL(((struct vnode *)fp->f_data), events, cred, td));
+	return (VOP_POLL(vp, events, cred, td));
 }
 
 /*

==== //depot/projects/trustedbsd/mac/sys/sys/mac.h#120 (text+ko) ====

@@ -191,6 +191,10 @@
  */
 extern int	mac_debug_label_fallback;
 
+#define	MAC_OP_VNODE_READ	1
+#define	MAC_OP_VNODE_WRITE	2
+#define	MAC_OP_VNODE_POLL	3
+
 /*
  * Kernel functions to manage and evaluate labels.
  */
@@ -288,6 +292,7 @@
 int	mac_cred_check_readlink_vnode(struct ucred *cred, struct vnode *vp);
 int	mac_cred_check_revoke_vnode(struct ucred *cred, struct vnode *vp);
 int	mac_cred_check_statfs(struct ucred *cred, struct mount *mp);
+int	mac_cred_check_vnode_op(struct ucred *cred, struct vnode *vp, int op);
 int	mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
 	    struct mac *extmac);
 int	mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,

==== //depot/projects/trustedbsd/mac/sys/sys/mac_policy.h#85 (text+ko) ====

@@ -316,6 +316,8 @@
 	/* XXX should be vm_prot_t, not u_char directly */
 	u_char	(*mpo_cred_check_vnode_mmap_perms)(struct ucred *cred,
 		    struct vnode *vp, struct label *label);
+	int	(*mpo_cred_check_vnode_op)(struct ucred *cred,
+		    struct vnode *vp, struct label *label, int op);
 	int	(*mpo_ifnet_check_send_mbuf)(struct ifnet *ifnet,
 		    struct label *ifnetlabel, struct mbuf *mbuf,
 		    struct label *mbuflabel);
@@ -429,6 +431,7 @@
 	MAC_CRED_CHECK_SIGNAL_PROC,
 	MAC_CRED_CHECK_STAT_VNODE,
 	MAC_CRED_CHECK_VNODE_MMAP_PERMS,
+	MAC_CRED_CHECK_VNODE_OP,
 	MAC_IFNET_CHECK_SEND_MBUF,
 	MAC_SOCKET_CHECK_RECEIVE_MBUF,
 };

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe p4-projects" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200207232146.g6NLknBV059031>