PERFORCE change 24154 for review

Brian Feldman green at freebsd.org
Fri Jan 24 23:32:38 GMT 2003


http://perforce.freebsd.org/chv.cgi?CH=24154

Change 24154 by green at green_laptop_2 on 2003/01/24 15:32:28

	Add the set of struct file MAC entry points, and enforce them
	in SEBSD (largely untested, other than not crashing).

Affected files ...

.. //depot/projects/trustedbsd/sebsd/sys/compat/linux/linux_file.c#2 edit
.. //depot/projects/trustedbsd/sebsd/sys/compat/svr4/svr4_filio.c#2 edit
.. //depot/projects/trustedbsd/sebsd/sys/compat/svr4/svr4_misc.c#2 edit
.. //depot/projects/trustedbsd/sebsd/sys/i386/ibcs2/ibcs2_misc.c#2 edit
.. //depot/projects/trustedbsd/sebsd/sys/kern/kern_descrip.c#2 edit
.. //depot/projects/trustedbsd/sebsd/sys/kern/kern_mac.c#2 edit
.. //depot/projects/trustedbsd/sebsd/sys/kern/sys_generic.c#2 edit
.. //depot/projects/trustedbsd/sebsd/sys/kern/uipc_usrreq.c#2 edit
.. //depot/projects/trustedbsd/sebsd/sys/kern/vfs_syscalls.c#2 edit
.. //depot/projects/trustedbsd/sebsd/sys/kern/vfs_vnops.c#2 edit
.. //depot/projects/trustedbsd/sebsd/sys/security/sebsd/sebsd.c#2 edit
.. //depot/projects/trustedbsd/sebsd/sys/security/sebsd/sebsd_labels.h#2 edit
.. //depot/projects/trustedbsd/sebsd/sys/sys/file.h#2 edit
.. //depot/projects/trustedbsd/sebsd/sys/sys/mac.h#2 edit
.. //depot/projects/trustedbsd/sebsd/sys/sys/mac_policy.h#2 edit

Differences ...

==== //depot/projects/trustedbsd/sebsd/sys/compat/linux/linux_file.c#2 (text+ko) ====

@@ -269,6 +269,13 @@
 		fdrop(fp, td);
 		return (EBADF);
 	}
+#ifdef MAC
+	error = mac_check_file_change_offset(td->td_ucred, fp);	
+	if (error) {
+		fdrop(fp, td);
+		return (EBADF);
+	}
+#endif	
 
 	vp = (struct vnode *) fp->f_data;
 	if (vp->v_type != VDIR) {

==== //depot/projects/trustedbsd/sebsd/sys/compat/svr4/svr4_filio.c#2 (text+ko) ====

@@ -28,6 +28,8 @@
  * $FreeBSD: src/sys/compat/svr4/svr4_filio.c,v 1.22 2002/12/14 01:56:24 alfred Exp $
  */
 
+#include "opt_mac.h"
+
 #include <sys/param.h>
 #include <sys/proc.h>
 #include <sys/systm.h>
@@ -186,18 +188,31 @@
 	struct filedesc *fdp = td->td_proc->p_fd;
 
 	*retval = 0;
+	error = 0;
 
 	FILEDESC_LOCK(fdp);
 	switch (cmd) {
 	case SVR4_FIOCLEX:
-		fdp->fd_ofileflags[fd] |= UF_EXCLOSE;
+#ifdef MAC
+		error = mac_check_file_change_ofileflags(td->td_ucred,
+		    fp, fdp->fd_ofileflags[uap->fd],
+		    fdp->fd_ofileflags[uap->fd] | UF_EXCLOSE);
+		if (error == 0)
+#endif
+			fdp->fd_ofileflags[fd] |= UF_EXCLOSE;
 		FILEDESC_UNLOCK(fdp);
-		return 0;
+		return (error);
 
 	case SVR4_FIONCLEX:
-		fdp->fd_ofileflags[fd] &= ~UF_EXCLOSE;
+#ifdef MAC
+		error = mac_check_file_change_ofileflags(td->td_ucred,
+		    fp, fdp->fd_ofileflags[uap->fd],
+		    fdp->fd_ofileflags[uap->fd] & ~UF_EXCLOSE);
+		if (error == 0)
+#endif
+			fdp->fd_ofileflags[fd] &= ~UF_EXCLOSE;
 		FILEDESC_UNLOCK(fdp);
-		return 0;
+		return (error);
 
 	case SVR4_FIOGETOWN:
 	case SVR4_FIOSETOWN:

==== //depot/projects/trustedbsd/sebsd/sys/compat/svr4/svr4_misc.c#2 (text+ko) ====

@@ -283,6 +283,14 @@
 		return error;
 	}
 
+#ifdef MAC
+	error = mac_check_file_change_offset(td->td_ucred, fp);
+	if (error) {
+		fdrop(fp, td);
+		return (error);
+	}
+#endif
+
 	nbytes = uap->nbytes;
 	if (nbytes == 1) {
 		nbytes = sizeof (struct svr4_dirent64);
@@ -450,6 +458,13 @@
 		fdrop(fp, td);
 		return (EBADF);
 	}
+#ifdef MAC
+	error = mac_check_file_change_offset(td->td_ucred, fp);
+	if (error) {
+		fdrop(fp, td);
+		return (error);
+	}
+#endif
 
 	vp = (struct vnode *)fp->f_data;
 	if (vp->v_type != VDIR) {

==== //depot/projects/trustedbsd/sebsd/sys/i386/ibcs2/ibcs2_misc.c#2 (text+ko) ====

@@ -323,6 +323,13 @@
 		fdrop(fp, td);
 		return (EBADF);
 	}
+#ifdef MAC
+	error = mac_check_file_change_offset(td->td_ucred, fp);
+	if (error) {
+		fdrop(fp, td);
+		return (error);
+	}
+#endif
 	vp = (struct vnode *)fp->f_data;
 	if (vp->v_type != VDIR) {	/* XXX  vnode readdir op should do this */
 		fdrop(fp, td);
@@ -480,6 +487,13 @@
 		fdrop(fp, td);
 		return (EBADF);
 	}
+#ifdef MAC
+	error = mac_check_file_change_offset(td->td_ucred, fp);
+	if (error) {
+		fdrop(fp, td);
+		return (error);
+	}
+#endif
 	vp = (struct vnode *)fp->f_data;
 	if (vp->v_type != VDIR) {
 		fdrop(fp, td);

==== //depot/projects/trustedbsd/sebsd/sys/kern/kern_descrip.c#2 (text+ko) ====

@@ -62,6 +62,7 @@
 #include <sys/stat.h>
 #include <sys/filio.h>
 #include <sys/fcntl.h>
+#include <sys/mac.h>
 #include <sys/unistd.h>
 #include <sys/resourcevar.h>
 #include <sys/event.h>
@@ -282,20 +283,36 @@
 		break;
 
 	case F_GETFD:
-		td->td_retval[0] = (*pop & UF_EXCLOSE) ? FD_CLOEXEC : 0;
+#ifdef MAC
+		error = mac_check_file_get_ofileflags(td->td_ucred, fp,
+		    *pop);
+		if (error == 0)
+#endif
+			td->td_retval[0] = (*pop & UF_EXCLOSE) ? FD_CLOEXEC : 0;
 		FILEDESC_UNLOCK(fdp);
 		break;
 
 	case F_SETFD:
-		*pop = (*pop &~ UF_EXCLOSE) |
-		    (arg & FD_CLOEXEC ? UF_EXCLOSE : 0);
+#ifdef MAC
+		error = mac_check_file_change_ofileflags(td->td_ucred, fp,
+		    *pop, (*pop &~ UF_EXCLOSE) |
+		    (arg & FD_CLOEXEC ? UF_EXCLOSE : 0));
+		if (error == 0)
+#endif
+			*pop = (*pop &~ UF_EXCLOSE) |
+			    (arg & FD_CLOEXEC ? UF_EXCLOSE : 0);
 		FILEDESC_UNLOCK(fdp);
 		break;
 
 	case F_GETFL:
 		FILE_LOCK(fp);
 		FILEDESC_UNLOCK(fdp);
-		td->td_retval[0] = OFLAGS(fp->f_flag);
+#ifdef MAC
+		error = mac_check_file_get_flags(td->td_ucred, fp,
+		    fp->f_flag);
+		if (error == 0)
+#endif
+			td->td_retval[0] = OFLAGS(fp->f_flag);
 		FILE_UNLOCK(fp);
 		break;
 
@@ -332,6 +349,15 @@
 		}
 #endif /* MAC */
 #endif
+#ifdef MAC
+		error = mac_check_file_change_flags(td->td_ucred, fp,
+		    fp->f_flag, (fp->f_flag & ~FCNTLFLAGS) |
+		    (FFLAGS(arg & ~O_ACCMODE) & FCNTLFLAGS));
+		if (error) {
+			fdrop(fp, td);
+			break;
+		}
+#endif
 		fp->f_flag &= ~FCNTLFLAGS;
 		fp->f_flag |= FFLAGS(arg & ~O_ACCMODE) & FCNTLFLAGS;
 		tmp = fp->f_flag & FNONBLOCK;
@@ -530,6 +556,14 @@
 	}
 	if (type == DUP_VARIABLE)
 		new = newfd;
+#ifdef MAC
+	error = mac_check_file_dup(td->td_ucred, fp, new);
+	if (error) {
+		FILEDESC_UNLOCK(fdp);
+		fdrop(fp, td);
+		return (error);
+	}
+#endif
 
 	/*
 	 * If the old file changed out from under us then treat it as a
@@ -1205,6 +1239,10 @@
 	fp->f_cred = crhold(td->td_ucred);
 	fp->f_ops = &badfileops;
 	fp->f_seqcount = 1;
+#ifdef MAC
+	mac_init_file(fp);
+	mac_create_file(fp->f_cred, fp);
+#endif
 	FILEDESC_LOCK(p->p_fd);
 	if ((fq = p->p_fd->fd_ofiles[0])) {
 		LIST_INSERT_AFTER(fq, fp, f_list);
@@ -1239,6 +1277,9 @@
 	LIST_REMOVE(fp, f_list);
 	nfiles--;
 	sx_xunlock(&filelist_lock);
+#ifdef MAC
+	mac_destroy_file(fp);
+#endif
 	crfree(fp->f_cred);
 	uma_zfree(file_zone, fp);
 }
@@ -1551,8 +1592,14 @@
 	 * may block and rip them out from under us.
 	 */
 	for (i = 0; i <= fdp->fd_lastfile; i++) {
+#ifdef MAC
+		if (fdp->fd_ofiles[i] != NULL &&
+		    ((fdp->fd_ofileflags[i] & UF_EXCLOSE) ||
+		    mac_check_file_inherit(td->td_ucred, fdp->fd_ofiles[i]))) {
+#else
 		if (fdp->fd_ofiles[i] != NULL &&
 		    (fdp->fd_ofileflags[i] & UF_EXCLOSE)) {
+#endif
 			struct file *fp;
 
 #if 0
@@ -1936,6 +1983,14 @@
 	if (uap->how & LOCK_UN) {
 		lf.l_type = F_UNLCK;
 		FILE_LOCK(fp);
+#ifdef MAC
+		error = mac_check_file_change_flags(td->td_ucred, fp,
+		    fp->f_flag, fp->f_flag & ~FHASLOCK);
+		if (error) {
+			FILE_UNLOCK(fp);
+			goto done2;
+		}
+#endif
 		fp->f_flag &= ~FHASLOCK;
 		FILE_UNLOCK(fp);
 		error = VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK);
@@ -1950,6 +2005,14 @@
 		goto done2;
 	}
 	FILE_LOCK(fp);
+#ifdef MAC
+	error = mac_check_file_change_flags(td->td_ucred, fp, fp->f_flag,
+	    fp->f_flag | FHASLOCK);
+	if (error) {
+		FILE_UNLOCK(fp);
+		goto done2;
+	}
+#endif
 	fp->f_flag |= FHASLOCK;
 	FILE_UNLOCK(fp);
 	error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf,
@@ -2013,6 +2076,13 @@
 		FILEDESC_UNLOCK(fdp);
 		return (EBADF);
 	}
+#ifdef MAC
+	error = mac_check_file_dup(td->td_ucred, wfp, dfd);
+	if (error) {
+		FILEDESC_UNLOCK(fdp);
+		return (error);
+	}
+#endif
 
 	/*
 	 * There are two cases of interest here.

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

@@ -125,6 +125,11 @@
     &mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
 TUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs);
 
+static int	mac_enforce_file = 1;
+SYSCTL_INT(_security_mac, OID_AUTO, enforce_file, CTLFLAG_RW,
+    &mac_enforce_file, 0, "Enforce MAC policy on file descriptors");
+TUNABLE_INT("security.mac.enforce_file", &mac_enforce_file);
+
 static int	mac_enforce_kld = 1;
 SYSCTL_INT(_security_mac, OID_AUTO, enforce_kld, CTLFLAG_RW,
     &mac_enforce_kld, 0, "Enforce MAC policy on kld operations");
@@ -183,7 +188,7 @@
 SYSCTL_NODE(_security_mac_debug, OID_AUTO, counters, CTLFLAG_RW, 0,
     "TrustedBSD MAC object counters");
 
-static unsigned int nmacmbufs, nmaccreds, nmacifnets, nmacbpfdescs,
+static unsigned int nmacmbufs, nmaccreds, nmacfiles, nmacifnets, nmacbpfdescs,
     nmacsockets, nmacmounts, nmactemp, nmacvnodes, nmacdevfsdirents,
     nmacipqs, nmacpipes, nmacprocs;
 
@@ -191,6 +196,8 @@
     &nmacmbufs, 0, "number of mbufs in use");
 SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, creds, CTLFLAG_RD,
     &nmaccreds, 0, "number of ucreds in use");
+SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, files, CTLFLAG_RD,
+    &nmacfiles, 0, "number of files in use");
 SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ifnets, CTLFLAG_RD,
     &nmacifnets, 0, "number of ifnets in use");
 SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipqs, CTLFLAG_RD,
@@ -678,6 +685,17 @@
 #endif
 }
 
+void
+mac_init_file(struct file *fp)
+{
+
+	mac_init_label(&fp->f_label);
+	MAC_PERFORM(init_file_label, &fp->f_label);
+#ifdef MAC_DEBUG
+	atomic_add_int(&nmacfiles, 1);
+#endif
+}
+
 static void
 mac_init_ifnet_label(struct label *label)
 {
@@ -886,6 +904,17 @@
 #endif
 }
 
+void
+mac_destroy_file(struct file *fp)
+{
+
+	MAC_PERFORM(destroy_file_label, &fp->f_label);
+	mac_destroy_label(&fp->f_label);
+#ifdef MAC_DEBUG
+	atomic_subtract_int(&nmacfiles, 1);
+#endif
+}
+
 static void
 mac_destroy_ifnet_label(struct label *label)
 {
@@ -1381,6 +1410,131 @@
 }
 
 int
+mac_check_file_create(struct ucred *cred)
+{
+	int error;
+
+	if (!mac_enforce_file)
+		return (0);
+	MAC_CHECK(check_file_create, cred);
+	return (error);
+}
+
+int
+mac_check_file_dup(struct ucred *cred, struct file *fp, int newfd)
+{
+	int error;
+
+	if (!mac_enforce_file)
+		return (0);
+	MAC_CHECK(check_file_dup, cred, fp, &fp->f_label, newfd);
+	return (error);
+}
+
+int
+mac_check_file_ioctl(struct ucred *cred, struct file *fp, u_long com)
+{
+	int error;
+
+	if (!mac_enforce_file)
+		return (0);
+	MAC_CHECK(check_file_ioctl, cred, fp, &fp->f_label, com);
+	return (error);
+}
+
+int
+mac_check_file_inherit(struct ucred *cred, struct file *fp)
+{
+	int error;
+
+	if (!mac_enforce_file)
+		return (0);
+	MAC_CHECK(check_file_inherit, cred, fp, &fp->f_label);
+	return (error);
+}
+
+int
+mac_check_file_receive(struct ucred *cred, struct file *fp)
+{
+	int error;
+
+	if (!mac_enforce_file)
+		return (0);
+	MAC_CHECK(check_file_receive, cred, fp, &fp->f_label);
+	return (error);
+}
+
+int
+mac_check_file_get_flags(struct ucred *cred, struct file *fp, u_int flags)
+{
+	int error;
+
+	if (!mac_enforce_file)
+		return (0);
+	MAC_CHECK(check_file_get_flags, cred, fp, &fp->f_label, flags);
+	return (error);
+}
+
+int
+mac_check_file_get_ofileflags(struct ucred *cred, struct file *fp, char flags)
+{
+	int error;
+
+	if (!mac_enforce_file)
+		return (0);
+	MAC_CHECK(check_file_get_ofileflags, cred, fp, &fp->f_label, flags);
+	return (error);
+}
+
+int
+mac_check_file_change_flags(struct ucred *cred, struct file *fp,
+    u_int oldflags, u_int newflags)
+{
+	int error;
+
+	if (!mac_enforce_file)
+		return (0);
+	MAC_CHECK(check_file_change_flags, cred, fp, &fp->f_label, oldflags,
+	    newflags);
+	return (error);
+}
+
+int
+mac_check_file_change_ofileflags(struct ucred *cred, struct file *fp,
+    char oldflags, char newflags)
+{
+	int error;
+
+	if (!mac_enforce_file)
+		return (0);
+	MAC_CHECK(check_file_change_ofileflags, cred, fp, &fp->f_label,
+	    oldflags, newflags);
+	return (error);
+}
+
+int
+mac_check_file_get_offset(struct ucred *cred, struct file *fp)
+{
+	int error;
+
+	if (!mac_enforce_file)
+		return (0);
+	MAC_CHECK(check_file_get_offset, cred, fp, &fp->f_label);
+	return (error);
+}
+
+int
+mac_check_file_change_offset(struct ucred *cred, struct file *fp)
+{
+	int error;
+
+	if (!mac_enforce_file)
+		return (0);
+	MAC_CHECK(check_file_change_offset, cred, fp, &fp->f_label);
+	return (error);
+}
+
+int
 mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int acc_mode)
 {
 	int error;
@@ -2044,6 +2198,13 @@
 }
 
 void
+mac_create_file(struct ucred *cred, struct file *fp)
+{
+
+	MAC_PERFORM(create_file, cred, fp, &fp->f_label);
+}
+
+void
 mac_create_socket(struct ucred *cred, struct socket *socket)
 {
 

==== //depot/projects/trustedbsd/sebsd/sys/kern/sys_generic.c#2 (text+ko) ====

@@ -40,6 +40,7 @@
  */
 
 #include "opt_ktrace.h"
+#include "opt_mac.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -66,6 +67,7 @@
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
+#include <sys/mac.h>
 #include <vm/vm.h>
 #include <vm/vm_page.h>
 
@@ -591,18 +593,30 @@
 	switch (com = uap->com) {
 	case FIONCLEX:
 		FILEDESC_LOCK(fdp);
-		fdp->fd_ofileflags[uap->fd] &= ~UF_EXCLOSE;
+#ifdef MAC
+		error = mac_check_file_change_ofileflags(td->td_ucred,
+		    fp, fdp->fd_ofileflags[uap->fd],
+		    fdp->fd_ofileflags[uap->fd] & ~UF_EXCLOSE);
+#endif
+		if (error == 0)
+			fdp->fd_ofileflags[uap->fd] &= ~UF_EXCLOSE;
 		FILEDESC_UNLOCK(fdp);
 		fdrop(fp, td);
 		mtx_unlock(&Giant);
-		return (0);
+		return (error);
 	case FIOCLEX:
 		FILEDESC_LOCK(fdp);
-		fdp->fd_ofileflags[uap->fd] |= UF_EXCLOSE;
+#ifdef MAC
+		error = mac_check_file_change_ofileflags(td->td_ucred,
+		    fp, fdp->fd_ofileflags[uap->fd],
+		    fdp->fd_ofileflags[uap->fd] | UF_EXCLOSE);
+#endif
+		if (error == 0)
+			fdp->fd_ofileflags[uap->fd] |= UF_EXCLOSE;
 		FILEDESC_UNLOCK(fdp);
 		fdrop(fp, td);
 		mtx_unlock(&Giant);
-		return (0);
+		return (error);
 	}
 
 	/*
@@ -649,6 +663,15 @@
 
 	case FIONBIO:
 		FILE_LOCK(fp);
+#ifdef MAC
+		error = mac_check_file_change_flags(td->td_ucred, fp,
+		    fp->f_flag, *(int *)data ? fp->f_flag | FNONBLOCK :
+		    fp->f_flag & ~FNONBLOCK);
+		if (error) {
+			FILE_UNLOCK(fp);
+			break;
+		}
+#endif
 		if ((tmp = *(int *)data))
 			fp->f_flag |= FNONBLOCK;
 		else
@@ -659,6 +682,15 @@
 
 	case FIOASYNC:
 		FILE_LOCK(fp);
+#ifdef MAC
+		error = mac_check_file_change_flags(td->td_ucred, fp,
+		    fp->f_flag, *(int *)data ? fp->f_flag | FASYNC :
+		    fp->f_flag & ~FASYNC);
+		if (error) {
+			FILE_UNLOCK(fp);
+			break;
+		}
+#endif
 		if ((tmp = *(int *)data))
 			fp->f_flag |= FASYNC;
 		else

==== //depot/projects/trustedbsd/sebsd/sys/kern/uipc_usrreq.c#2 (text+ko) ====

@@ -1040,6 +1040,21 @@
 			fdp = (int *)
 			    CMSG_DATA(mtod(*controlp, struct cmsghdr *));
 			for (i = 0; i < newfds; i++) {
+#ifdef MAC
+				/*
+				 * Don't pass an error message along, but
+				 * do decrease the message header length
+				 * by the file descriptor's size.
+				 */
+				if (mac_check_file_receive(td->td_ucred, *rp)) {
+					fp = *rp;
+					*rp++ = 0;
+					unp_discard(fp);
+					mtod(*controlp, struct cmsghdr *)->
+					    cmsg_len -= sizeof(int);
+					continue;
+				}
+#endif
 				if (fdalloc(td, 0, &f))
 					panic("unp_externalize fdalloc failed");
 				fp = *rp++;

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

@@ -742,6 +742,12 @@
 		type = F_FLOCK;
 		if ((flags & FNONBLOCK) == 0)
 			type |= F_WAIT;
+#ifdef MAC
+		error = mac_check_file_change_flags(td->td_ucred, fp,
+		    fp->f_flag, fp->f_flag | FHASLOCK);
+		if (error)
+			goto bad;
+#endif
 		if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf,
 			    type)) != 0)
 			goto bad;
@@ -1320,6 +1326,16 @@
 		fdrop(fp, td);
 		return (ESPIPE);
 	}
+#ifdef MAC
+	if (uap->whence == L_INCR && uap->offset == 0)
+		error = mac_check_file_get_offset(cred, fp);
+	else
+		error = mac_check_file_change_offset(cred, fp);
+	if (error) {
+		fdrop(fp, td);
+		return (error);
+	}
+#endif
 	vp = (struct vnode *)fp->f_data;
 	noneg = (vp->v_type != VCHR);
 	offset = uap->offset;
@@ -3068,6 +3084,13 @@
 		fdrop(fp, td);
 		return (EBADF);
 	}
+#ifdef MAC
+	error = mac_check_file_change_offset(td->td_ucred, fp);
+	if (error) {
+		fdrop(fp, td);
+		return (error);
+	}
+#endif
 	vp = (struct vnode *)fp->f_data;
 unionread:
 	if (vp->v_type != VDIR) {
@@ -3222,6 +3245,13 @@
 		fdrop(fp, td);
 		return (EINVAL);
 	}
+#ifdef MAC
+	error = mac_check_file_change_offset(td->td_ucred, fp);
+	if (error) {
+		fdrop(fp, td);
+		return (error);
+	}
+#endif
 	aiov.iov_base = uap->buf;
 	aiov.iov_len = uap->count;
 	auio.uio_iov = &aiov;

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

@@ -504,6 +504,13 @@
 	struct vnode *vp;
 	int error, ioflag;
 
+#ifdef MAC
+	if ((flags & FOF_OFFSET) == 0) {
+		error = mac_check_file_change_offset(td->td_ucred, fp);
+		if (error)
+			return (error);
+	}
+#endif
 	mtx_lock(&Giant);
 	KASSERT(uio->uio_td == td, ("uio_td %p is not td %p",
 	    uio->uio_td, td));
@@ -552,6 +559,13 @@
 	struct mount *mp;
 	int error, ioflag;
 
+#ifdef MAC
+	if ((flags & FOF_OFFSET) == 0) {
+		error = mac_check_file_change_offset(td->td_ucred, fp);
+		if (error)
+			return (error);
+	}
+#endif
 	mtx_lock(&Giant);
 	KASSERT(uio->uio_td == td, ("uio_td %p is not td %p",
 	    uio->uio_td, td));

==== //depot/projects/trustedbsd/sebsd/sys/security/sebsd/sebsd.c#2 (text+ko) ====

@@ -267,6 +267,16 @@
 }
 
 static void
+sebsd_init_file_label(struct label *label)
+{
+	struct file_security_struct *new_fsec;
+
+	new_fsec = malloc(sizeof(*new_fsec), M_SEBSD, M_ZERO | M_WAITOK);
+	new_fsec->sid = new_fsec->sid = SECINITSID_UNLABELED;
+	SLOT(label) = new_fsec;
+}
+
+static void
 sebsd_init_mount_label(struct label *label)
 {
 	struct mount_security_struct *sbsec;
@@ -425,6 +435,18 @@
 }
 
 static void
+sebsd_create_file(struct ucred *cred, struct file *fp, struct label *label)
+{
+	struct task_security_struct *tsec;
+	struct file_security_struct *fsec;
+
+	tsec = SLOT(&cred->cr_label);
+	fsec = SLOT(label);
+
+	fsec->sid = tsec->sid;
+}
+
+static void
 sebsd_create_devfs_device(struct mount *mp, dev_t dev,
     struct devfs_dirent *devfs_dirent, struct label *label,
     const char *fullpath)
@@ -631,7 +653,7 @@
 		break;
 	default:
 		printf("%s:  security_fs_use(%s) returned unrecognized "
-	            "behavior %d\n", __FUNCTION__, mp->mnt_vfc->vfc_name, 
+		    "behavior %d\n", __FUNCTION__, mp->mnt_vfc->vfc_name, 
 		    behavior);
 		behavior = SECURITY_FS_USE_NONE;
 		break;
@@ -838,7 +860,7 @@
 
 	if (strcmp("sebsd", element_name) != 0)
 		return (0);
-        (*claimed)++;
+	(*claimed)++;
 
 	if (strlcpy(context, element_data, sizeof(context)) >=
 	    sizeof(context))
@@ -1061,7 +1083,7 @@
 	AVC_AUDIT_DATA_INIT(&ad, FS);
 	ad.u.fs.vp = vp;
 
-        if (newsid == task->sid) {
+	if (newsid == task->sid) {
 		rc = avc_has_perm_audit(task->sid, file->sid, SECCLASS_FILE, 
 		    FILE__EXECUTE_NO_TRANS, &ad);
 
@@ -1438,9 +1460,9 @@
 {
 	security_context_t context;
 	u_int32_t context_len;
-        int error;
+	int error;
 
-        if (strcmp("sebsd", element_name) != 0)
+	if (strcmp("sebsd", element_name) != 0)
 		return (0);
 
 	(*claimed)++;
@@ -1536,11 +1558,95 @@
 	    CAPABILITY__SYS_MODULE, NULL));
 }
 
+/*
+ * Simplify all fd permissions to just "use" for now.  The ones we implement
+ * in SEBSD roughly correlate to the SELinux FD__USE permissions, and not
+ * the fine-grained FLASK permissions.
+ */
+static int
+sebsd_check_file_get_flags(struct ucred *cred, struct file *fp,
+    struct label *fplabel, u_int flags)
+{
+	struct task_security_struct *tsec;
+	struct file_security_struct *fsec;
+
+	tsec = SLOT(&cred->cr_label);
+	fsec = SLOT(fplabel);
+	return (avc_has_perm_audit(tsec->sid, fsec->sid, SECCLASS_FILE,
+	    FD__USE, NULL));
+}
+
+static int
+sebsd_check_file_get_ofileflags(struct ucred *cred, struct file *fp,
+    struct label *fplabel, char flags)
+{
+	struct task_security_struct *tsec;
+	struct file_security_struct *fsec;
+
+	tsec = SLOT(&cred->cr_label);
+	fsec = SLOT(fplabel);
+	return (avc_has_perm_audit(tsec->sid, fsec->sid, SECCLASS_FILE,
+	    FD__USE, NULL));
+}
+
+static int
+sebsd_check_file_change_flags(struct ucred *cred, struct file *fp,
+    struct label *fplabel, u_int oldflags, u_int newflags)
+{
+	struct task_security_struct *tsec;
+	struct file_security_struct *fsec;
+
+	tsec = SLOT(&cred->cr_label);
+	fsec = SLOT(fplabel);
+	return (avc_has_perm_audit(tsec->sid, fsec->sid, SECCLASS_FILE,
+	    FD__USE, NULL));
+}
+
+static int
+sebsd_check_file_change_ofileflags(struct ucred *cred, struct file *fp,
+    struct label *fplabel, char oldflags, char newflags)
+{
+	struct task_security_struct *tsec;
+	struct file_security_struct *fsec;
+
+	tsec = SLOT(&cred->cr_label);
+	fsec = SLOT(fplabel);
+	return (avc_has_perm_audit(tsec->sid, fsec->sid, SECCLASS_FILE,
+	    FD__USE, NULL));
+}
+
+static int
+sebsd_check_file_get_offset(struct ucred *cred, struct file *fp,
+    struct label *fplabel)
+{
+	struct task_security_struct *tsec;
+	struct file_security_struct *fsec;
+
+	tsec = SLOT(&cred->cr_label);
+	fsec = SLOT(fplabel);
+	return (avc_has_perm_audit(tsec->sid, fsec->sid, SECCLASS_FILE,
+	    FD__USE, NULL));
+}
+
+static int
+sebsd_check_file_change_offset(struct ucred *cred, struct file *fp,
+    struct label *fplabel)
+{
+	struct task_security_struct *tsec;
+	struct file_security_struct *fsec;
+
+	tsec = SLOT(&cred->cr_label);
+	fsec = SLOT(fplabel);
+	return (avc_has_perm_audit(tsec->sid, fsec->sid, SECCLASS_FILE,
+	    FD__USE, NULL));
+}
+
 static struct mac_policy_ops sebsd_ops = {
 	/* Init Labels */
 	.mpo_init = sebsd_init,
 	.mpo_init_cred_label = sebsd_init_cred_label,
 	.mpo_init_devfsdirent_label = sebsd_init_vnode_label,
+	.mpo_init_file_label = sebsd_init_file_label,
 	.mpo_init_mount_label = sebsd_init_mount_label,
 	.mpo_init_mount_fs_label = sebsd_init_mount_fs_label,
 	.mpo_init_vnode_label = sebsd_init_vnode_label,
@@ -1549,6 +1655,7 @@
 	.mpo_destroy = sebsd_destroy,
 	.mpo_destroy_cred_label = sebsd_destroy_label,
 	.mpo_destroy_devfsdirent_label = sebsd_destroy_label,
+	.mpo_destroy_file_label = sebsd_destroy_label,
 	.mpo_destroy_mount_label = sebsd_destroy_label,
 	.mpo_destroy_mount_fs_label = sebsd_destroy_label,
 	.mpo_destroy_vnode_label = sebsd_destroy_label,
@@ -1567,6 +1674,7 @@
 	.mpo_create_devfs_device = sebsd_create_devfs_device,
 	.mpo_create_devfs_directory = sebsd_create_devfs_directory,
 	.mpo_create_devfs_symlink = sebsd_create_devfs_symlink,
+	.mpo_create_file = sebsd_create_file,
 	.mpo_create_proc0 = sebsd_create_proc0,
 	.mpo_create_proc1 = sebsd_create_proc1,
 	.mpo_create_mount = sebsd_create_mount,
@@ -1578,6 +1686,12 @@
 
 	/* Check Labels */
 	.mpo_check_cred_relabel = sebsd_check_cred_relabel,
+	.mpo_check_file_get_flags = sebsd_check_file_get_flags,
+	.mpo_check_file_get_ofileflags = sebsd_check_file_get_ofileflags,
+	.mpo_check_file_get_offset = sebsd_check_file_get_offset,
+	.mpo_check_file_change_flags = sebsd_check_file_change_flags,
+	.mpo_check_file_change_ofileflags = sebsd_check_file_change_ofileflags,
+	.mpo_check_file_change_offset = sebsd_check_file_change_offset,
 	.mpo_check_kld_stat = sebsd_check_kld_stat,
 	.mpo_check_kld_load = sebsd_check_kld_load,
 	.mpo_check_kld_unload = sebsd_check_kld_unload,

==== //depot/projects/trustedbsd/sebsd/sys/security/sebsd/sebsd_labels.h#2 (text+ko) ====

@@ -48,6 +48,10 @@
 	avc_entry_ref_t avcr;
 };
 
+struct file_security_struct {
+	security_id_t sid;
+};
+
 struct vnode_security_struct {
 	security_id_t task_sid;
 	security_id_t sid;

==== //depot/projects/trustedbsd/sebsd/sys/sys/file.h#2 (text+ko) ====

@@ -45,6 +45,7 @@
 #include <sys/queue.h>
 #include <sys/_lock.h>
 #include <sys/_mutex.h>
+#include <sys/_label.h>
 
 struct stat;
 struct thread;
@@ -109,6 +110,7 @@
 	void	*f_data;		/* vnode or socket */
 	u_int	f_flag;		/* see fcntl.h */
 	struct mtx	*f_mtxp;	/* mutex to protect data */
+	struct label	f_label;	/* MAC label */
 };
 
 #endif /* _KERNEL */

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

@@ -113,6 +113,7 @@
 struct bpf_d;
 struct componentname;
 struct devfs_dirent;
+struct file;
 struct ifnet;
 struct ifreq;
 struct image_params;
@@ -140,6 +141,7 @@
 void	mac_init_bpfdesc(struct bpf_d *);
 void	mac_init_cred(struct ucred *);
 void	mac_init_devfsdirent(struct devfs_dirent *);
+void	mac_init_file(struct file *);
 void	mac_init_ifnet(struct ifnet *);
 void	mac_init_ipq(struct ipq *);
 int	mac_init_socket(struct socket *, int flag);
@@ -153,6 +155,7 @@
 void	mac_destroy_bpfdesc(struct bpf_d *);
 void	mac_destroy_cred(struct ucred *);
 void	mac_destroy_devfsdirent(struct devfs_dirent *);
+void	mac_destroy_file(struct file *);
 void	mac_destroy_ifnet(struct ifnet *);
 void	mac_destroy_ipq(struct ipq *);
 void	mac_destroy_socket(struct socket *);
@@ -178,6 +181,7 @@
 void	mac_create_devfs_symlink(struct ucred *cred, struct mount *mp,
 	    struct devfs_dirent *dd, struct devfs_dirent *de,
 	    const char *fullpath);

>>> TRUNCATED FOR MAIL (1000 lines) <<<
To Unsubscribe: send mail to majordomo at trustedbsd.org
with "unsubscribe trustedbsd-cvs" in the body of the message



More information about the trustedbsd-cvs mailing list