Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 1 Jun 2002 20:42:47 -0700 (PDT)
From:      Robert Watson <rwatson@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 12286 for review
Message-ID:  <200206020342.g523glD82295@freefall.freebsd.org>

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

Change 12286 by rwatson@rwatson_curry on 2002/06/01 20:41:47

	Convert MLS to the new world order, largely based on the Biba work.
	Some XXX's still, and a panic in the statfs code on NFS boxes
	for some reason.

Affected files ...

... //depot/projects/trustedbsd/mac/sys/security/mac_mls/mac_mls.c#32 edit

Differences ...

==== //depot/projects/trustedbsd/mac/sys/security/mac_mls/mac_mls.c#32 (text+ko) ====

@@ -34,11 +34,12 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: $
+ * $FreeBSD$
  */
+
 /*
  * Developed by the TrustedBSD Project.
- * Multi-Level Security Policy.
+ * MLS fixed label mandatory confidentiality policy.
  */
 
 #include <sys/types.h>
@@ -58,991 +59,1644 @@
 #include <sys/socketvar.h>
 #include <sys/sysctl.h>
 
+#include <fs/devfs/devfs.h>
+
 #include <net/bpfdesc.h>
 #include <net/if.h>
 #include <net/if_types.h>
 #include <net/if_var.h>
 
+#include <netinet/in.h>
+#include <netinet/ip_var.h>
+
 #include <security/mac_mls/mac_mls.h>
 
 SYSCTL_DECL(_security_mac);
 
 SYSCTL_NODE(_security_mac, OID_AUTO, mls, CTLFLAG_RW, 0,
-    "TrustedBSD Multi-Level Security sensitivity policy controls");
+    "TrustedBSD mac_mls policy controls");
 
-static int	mac_mls_enabled = 1;
+static int	mac_mls_enabled = 0;
 SYSCTL_INT(_security_mac_mls, OID_AUTO, enabled, CTLFLAG_RW,
-    &mac_mls_enabled, 0, "Enforce MLS sensitivity policy");
-TUNABLE_INT("security.mac.mls.enabled", &mac_mls_enabled);
+    &mac_mls_enabled, 0, "Enforce MAC/MLS policy");
+
+static int	destroyed_not_inited;
+SYSCTL_INT(_security_mac_mls, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
+    &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
+
+static int	slot;
+#define	SLOT(l)	((struct mac_mls *)LABEL_TO_SLOT((l), slot).l_ptr)
+
+MALLOC_DEFINE(M_MACMLS, "mls label", "MAC/MLS labels");
+
+static struct mac_mls *
+mls_alloc(int how)
+{
+	struct mac_mls *mac_mls;
+
+	mac_mls = malloc(sizeof(struct mac_mls), M_MACMLS, M_ZERO | how);
+
+	return (mac_mls);
+}
+
+static void
+mls_free(struct mac_mls *mac_mls)
+{
+
+	if (mac_mls != NULL)
+		free(mac_mls, M_MACMLS);
+	else
+		atomic_add_int(&destroyed_not_inited, 1);
+}
 
 static int
-mac_mls_element_dominate(struct mac_mls_element *labela,
-    struct mac_mls_element *labelb)
+mac_mls_dominate_element(struct mac_mls_element *a,
+    struct mac_mls_element *b)
 {
 
-	switch (labela->mme_type) {
-	case MAC_MLS_TYPE_LEVEL:
-		switch (labelb->mme_type) {
+	switch(a->mme_type) {
+	case MAC_MLS_TYPE_EQUAL:
+	case MAC_MLS_TYPE_HIGH:
+		return (1);
+
+	case MAC_MLS_TYPE_LOW:
+		switch (b->mme_type) {
 		case MAC_MLS_TYPE_LEVEL:
-			return (labela->mme_level >= labelb->mme_level);
-		case MAC_MLS_TYPE_LOW:
-			return (1);
 		case MAC_MLS_TYPE_HIGH:
 			return (0);
+
 		case MAC_MLS_TYPE_EQUAL:
+		case MAC_MLS_TYPE_LOW:
 			return (1);
+
 		default:
-			panic("mac_mls_element_dominate(): Unknown "
-			    "labelb mme_type (%d)\n", labelb->mme_type);
+			panic("mac_mls_dominate_element: b->mme_type invalid");
 		}
-	case MAC_MLS_TYPE_LOW:
-		switch (labelb->mme_type) {
-		case MAC_MLS_TYPE_LEVEL:
-			return (0);
+
+	case MAC_MLS_TYPE_LEVEL:
+		switch (b->mme_type) {
+		case MAC_MLS_TYPE_EQUAL:
 		case MAC_MLS_TYPE_LOW:
 			return (1);
+
 		case MAC_MLS_TYPE_HIGH:
 			return (0);
-		case MAC_MLS_TYPE_EQUAL:
-			return (1);
+
+		case MAC_MLS_TYPE_LEVEL:
+			return (a->mme_level >= b->mme_level);
+
 		default:
-			panic("mac_mls_element_dominate(): Unknown "
-			    "labelb mme_type (%d)\n", labelb->mme_type);
+			panic("mac_mls_dominate_element: b->mme_type invalid");
 		}
-	case MAC_MLS_TYPE_HIGH:
-		return (1);
-	case MAC_MLS_TYPE_EQUAL:
-		return (1);
+
 	default:
-		panic("mac_mls_element_dominate(): Unknown labela "
-		    "mme_type (%d)\n", labela->mme_type);
+		panic("mac_mls_dominate_element: a->mme_type invalid");
 	}
+
+	return (0);
 }
 
 static int
-mac_mls_single_dominate(struct mac *labela, struct mac *labelb)
+mac_mls_range_in_range(struct mac_mls *rangea, struct mac_mls *rangeb)
 {
 
-	KASSERT((labela->m_mls.mm_flags & MAC_MLS_FLAG_SINGLE) != 0,
-	    ("mac_mls_single_dominate: labela does not have valid single"));
-	KASSERT((labelb->m_mls.mm_flags & MAC_MLS_FLAG_SINGLE) != 0,
-	    ("mac_mls_single_dominate: labelb does not have valid single"));
-
-	return (mac_mls_element_dominate(&labela->m_mls.mm_single,
-	    &labelb->m_mls.mm_single));
+	return (mac_mls_dominate_element(&rangea->mm_rangehigh,
+	    &rangeb->mm_rangehigh) &&
+	    mac_mls_dominate_element(&rangeb->mm_rangelow,
+	    &rangea->mm_rangelow));
 }
 
-/*
- * Syntactic checks of label: 0 for success, else an errno.
- */
 static int
-mac_mls_element_valid(struct mac_mls_element *element)
+mac_mls_single_in_range(struct mac_mls *single, struct mac_mls *range)
 {
 
-	switch(element->mme_type) {
-	case MAC_MLS_TYPE_LEVEL:
-		break;
-	case MAC_MLS_TYPE_HIGH:
-	case MAC_MLS_TYPE_LOW:
-	case MAC_MLS_TYPE_EQUAL:
-		if (element->mme_level != 0)
-			return (EINVAL);
-		break;
-	default:
-		return (EINVAL);
-	}
-	return (0);
+	return (mac_mls_dominate_element(&range->mm_rangehigh,
+	    &single->mm_single) &&
+	    mac_mls_dominate_element(&single->mm_single,
+	    &range->mm_rangelow));
+
+	return (1);
 }
 
 static int
-mac_mls_label_valid(struct mac *label)
+mac_mls_dominate_single(struct mac_mls *a, struct mac_mls *b)
 {
-	int error;
+	KASSERT((a->mm_flags & MAC_MLS_FLAG_SINGLE) != 0,
+	    ("mac_mls_dominate_single: a not single"));
+	KASSERT((b->mm_flags & MAC_MLS_FLAG_SINGLE) != 0,
+	    ("mac_mls_dominate_single: b not single"));
 
-	if ((label->m_mls.mm_flags & ~MAC_MLS_FLAGS_BOTH) != 0)
-		return (EINVAL);
-	if (label->m_mls.mm_flags & MAC_MLS_FLAG_SINGLE) {
-		error = mac_mls_element_valid(&label->m_mls.mm_single);
-		if (error)
-			return (error);
-	}
-	if (label->m_mls.mm_flags & MAC_MLS_FLAG_RANGE) {
-		error = mac_mls_element_valid(&label->m_mls.mm_rangelow);
-		if (error)
-			return (error);
-		error = mac_mls_element_valid(&label->m_mls.mm_rangehigh);
-		if (error)
-			return (error);
-		if (!(mac_mls_element_dominate(&label->m_mls.mm_rangehigh,
-		    &label->m_mls.mm_rangelow)))
-			return (EINVAL);
-	}
-	return (0);
+	return (mac_mls_dominate_element(&a->mm_single, &b->mm_single));
 }
 
 static int
-mac_mls_element_equal(struct mac_mls_element *labela,
-    struct mac_mls_element *labelb)
+mac_mls_equal_element(struct mac_mls_element *a, struct mac_mls_element *b)
 {
 
-	return (mac_mls_element_dominate(labela, labelb) &&
-	    mac_mls_element_dominate(labelb, labela));
+	if (a->mme_type == MAC_MLS_TYPE_EQUAL ||
+	    b->mme_type == MAC_MLS_TYPE_EQUAL)
+		return (1);
+
+	return (a->mme_type == b->mme_type && a->mme_level == b->mme_level);
 }
 
 static int
-mac_mls_single_equal(struct mac *labela, struct mac *labelb)
+mac_mls_equal_range(struct mac_mls *a, struct mac_mls *b)
 {
 
-	KASSERT((labela->m_mls.mm_flags & MAC_MLS_FLAG_SINGLE) != 0,
-	    ("mac_mls_single_equal: labela does not have valid single"));
-	KASSERT((labelb->m_mls.mm_flags & MAC_MLS_FLAG_SINGLE) != 0,
-	    ("mac_mls_single_equal: labelb does not have valid single"));
+	KASSERT((a->mm_flags & MAC_MLS_FLAG_RANGE) != 0,
+	    ("mac_mls_equal_range: a not range"));
+	KASSERT((b->mm_flags & MAC_MLS_FLAG_RANGE) != 0,
+	    ("mac_mls_equal_range: b not range"));
 
-	return (mac_mls_element_equal(&labela->m_mls.mm_single,
-	    &labelb->m_mls.mm_single));
+	return (mac_mls_equal_element(&a->mm_rangelow, &b->mm_rangelow) &&
+	    mac_mls_equal_element(&a->mm_rangehigh, &b->mm_rangehigh));
 }
 
 static int
-mac_mls_equal(struct mac *labela, struct mac *labelb)
+mac_mls_equal_single(struct mac_mls *a, struct mac_mls *b)
 {
-	int single_match, rangelow_match, rangehigh_match;
+
+	KASSERT((a->mm_flags & MAC_MLS_FLAG_SINGLE) != 0,
+	    ("mac_mls_equal_single: a not single"));
+	KASSERT((b->mm_flags & MAC_MLS_FLAG_SINGLE) != 0,
+	    ("mac_mls_equal_single: b not single"));
 
-	single_match = mac_mls_element_equal(&labela->m_mls.mm_single,
-	    &labelb->m_mls.mm_single);
-	rangelow_match = mac_mls_element_equal(&labela->m_mls.mm_rangelow,
-	    &labelb->m_mls.mm_rangelow);
-	rangehigh_match = mac_mls_element_equal(&labela->m_mls.mm_rangehigh,
-	    &labelb->m_mls.mm_rangehigh);
-	return (single_match && rangelow_match && rangehigh_match);
+	return (mac_mls_equal_element(&a->mm_single, &b->mm_single));
 }
 
 static int
-mac_mls_single_in_range(struct mac *labelsingle, struct mac *labelrange)
+mac_mls_valid(struct mac_mls *mac_mls)
 {
-	int between = 1;
+
+	if (mac_mls->mm_flags & MAC_MLS_FLAG_SINGLE) {
+		switch (mac_mls->mm_single.mme_type) {
+		case MAC_MLS_TYPE_LEVEL:
+			break;
+
+		case MAC_MLS_TYPE_EQUAL:
+		case MAC_MLS_TYPE_HIGH:
+		case MAC_MLS_TYPE_LOW:
+			if (mac_mls->mm_single.mme_level != 0)
+				return (EINVAL);
+			break;
+
+		default:
+			return (EINVAL);
+		}
+	} else {
+		if (mac_mls->mm_single.mme_type != MAC_MLS_TYPE_UNDEF)
+			return (EINVAL);
+	}
+
+	if (mac_mls->mm_flags & MAC_MLS_FLAG_RANGE) {
+		switch (mac_mls->mm_rangelow.mme_type) {
+		case MAC_MLS_TYPE_LEVEL:
+			break;
+
+		case MAC_MLS_TYPE_EQUAL:
+		case MAC_MLS_TYPE_HIGH:
+		case MAC_MLS_TYPE_LOW:
+			if (mac_mls->mm_rangelow.mme_level != 0)
+				return (EINVAL);
+			break;
+
+		default:
+			return (EINVAL);
+		}
+
+		switch (mac_mls->mm_rangehigh.mme_type) {
+		case MAC_MLS_TYPE_LEVEL:
+			break;
+
+		case MAC_MLS_TYPE_EQUAL:
+		case MAC_MLS_TYPE_HIGH:
+		case MAC_MLS_TYPE_LOW:
+			if (mac_mls->mm_rangehigh.mme_level != 0)
+				return (EINVAL);
+			break;
+
+		default:
+			return (EINVAL);
+		}
+		if (!mac_mls_dominate_element(&mac_mls->mm_rangehigh,
+		    &mac_mls->mm_rangelow))
+			return (EINVAL);
+	} else {
+		if (mac_mls->mm_rangelow.mme_type != MAC_MLS_TYPE_UNDEF ||
+		    mac_mls->mm_rangehigh.mme_type != MAC_MLS_TYPE_UNDEF)
+			return (EINVAL);
+	}
 
-	between &= mac_mls_element_dominate(&labelrange->m_mls.mm_rangehigh,
-	    &labelsingle->m_mls.mm_single);
-	between &= mac_mls_element_dominate(&labelsingle->m_mls.mm_single,
-	    &labelrange->m_mls.mm_rangelow);
-	return (between);
+	return (0);
 }
 
 static void
-mac_mls_init_label(struct mac *label)
+mac_mls_set_range(struct mac_mls *mac_mls, u_short typelow,
+    u_short levellow, u_short typehigh, u_short levelhigh)
 {
 
-	bzero(&label->m_mls, sizeof(label->m_mls));
+	mac_mls->mm_rangelow.mme_type = typelow;
+	mac_mls->mm_rangelow.mme_level = levellow;
+	mac_mls->mm_rangehigh.mme_type = typehigh;
+	mac_mls->mm_rangehigh.mme_level = levelhigh;
 }
 
 static void
-mac_mls_set_single(struct mac *label, u_short type, u_short level)
+mac_mls_set_single(struct mac_mls *mac_mls, u_short type, u_short level)
 {
 
-	label->m_mls.mm_single.mme_type = type;
-	label->m_mls.mm_single.mme_level = level;
-	label->m_mls.mm_flags |= MAC_MLS_FLAG_SINGLE;
+	mac_mls->mm_single.mme_type = type;
+	mac_mls->mm_single.mme_level = level;
+	mac_mls->mm_flags |= MAC_MLS_FLAG_SINGLE;
 }
 
 static void
-mac_mls_set_range(struct mac *label, u_short typelow, u_short levellow,
-    u_short typehigh, u_short levelhigh)
+mac_mls_copy_range(struct mac_mls *labelfrom, struct mac_mls *labelto)
 {
+	KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_RANGE) != 0,
+	    ("mac_mls_copy_range: labelfrom not range"));
 
-	label->m_mls.mm_rangelow.mme_type = typelow;
-	label->m_mls.mm_rangelow.mme_level = levellow;
-	label->m_mls.mm_rangehigh.mme_type = typehigh;
-	label->m_mls.mm_rangehigh.mme_level = levelhigh;
-	label->m_mls.mm_flags |= MAC_MLS_FLAG_RANGE;
+	labelto->mm_rangelow = labelfrom->mm_rangelow;
+	labelto->mm_rangehigh = labelfrom->mm_rangehigh;
+	labelto->mm_flags |= MAC_MLS_FLAG_RANGE;
 }
 
 static void
-mac_mls_copy_label(struct mac *labelfrom, struct mac *labelto)
+mac_mls_copy_single(struct mac_mls *labelfrom, struct mac_mls *labelto)
 {
 
-	bcopy(&labelfrom->m_mls, &labelto->m_mls, sizeof(labelto->m_mls));
+	KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_SINGLE) != 0,
+	    ("mac_mls_copy_single: labelfrom not single"));
+
+	labelto->mm_single = labelfrom->mm_single;
+	labelto->mm_flags |= MAC_MLS_FLAG_SINGLE;
 }
 
 static void
-mac_mls_copy_single(struct mac *labelfrom, struct mac *labelto)
+mac_mls_copy_single_to_range(struct mac_mls *labelfrom,
+    struct mac_mls *labelto)
 {
 
-	KASSERT((labelfrom->m_mls.mm_flags & MAC_MLS_FLAG_SINGLE) != 0,
-	    ("mac_mls_copy_single: labelfrom not single"));
+	KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_SINGLE) != 0,
+	    ("mac_mls_copy_single_to_range: labelfrom not single"));
+
+	labelto->mm_rangelow = labelfrom->mm_single;
+	labelto->mm_rangehigh = labelfrom->mm_single;
+	labelto->mm_flags |= MAC_MLS_FLAG_RANGE;
+}
+
+/*
+ * Policy module operations.
+ */
+static void
+mac_mls_destroy(struct mac_policy_conf *conf)
+{
 
-	bcopy(&labelfrom->m_mls.mm_single, &labelto->m_mls.mm_single,
-	    sizeof(labelto->m_mls.mm_single));
-	labelto->m_mls.mm_flags |= MAC_MLS_FLAG_SINGLE;
 }
 
-#if 0
 static void
-mac_mls_copy_range(struct mac *labelfrom, struct mac *labelto)
+mac_mls_init(struct mac_policy_conf *conf)
 {
 
-	bcopy(&labelfrom->m_mls.mm_rangelow, &labelto->m_mls.mm_rangelow,
-	    sizeof(labelto->m_mls.mm_rangelow));
-	bcopy(&labelfrom->m_mls.mm_rangehigh, &labelto->m_mls.mm_rangehigh,
-	    sizeof(labelto->m_mls.mm_rangehigh));
-	labelto->m_mls.mm_flags |= MAC_MLS_FLAG_RANGE;
 }
-#endif
 
 /*
- * Initialize system processes as MAC_MLS_TYPE_EQUAL so that they can
- * access any system resource with impunity.
+ * Label operations.
  */
 static void
-mac_mls_create_proc0(struct ucred *cred)
+mac_mls_init_bpfdesc(struct bpf_d *bpf_d, struct label *label)
+{
+
+	SLOT(label) = mls_alloc(M_WAITOK);
+}
+
+static void
+mac_mls_init_devfsdirent(struct devfs_dirent *devfs_dirent,
+    struct label *label)
 {
 
-	mac_mls_init_label(&cred->cr_label);
-	mac_mls_set_single(&cred->cr_label, MAC_MLS_TYPE_EQUAL, 0);
-	mac_mls_set_range(&cred->cr_label, MAC_MLS_TYPE_LOW, 0,
-	    MAC_MLS_TYPE_HIGH, 0);
+	SLOT(label) = mls_alloc(M_WAITOK);
 }
 
-/*
- * Initialize user processes as MAC_MLS_TYPE_LOW to allow the user boot
- * sequence to rely on low-sensitivity objects.
- */
 static void
-mac_mls_create_proc1(struct ucred *cred)
+mac_mls_init_ifnet(struct ifnet *ifnet, struct label *label)
 {
 
-	mac_mls_init_label(&cred->cr_label);
-	mac_mls_set_single(&cred->cr_label, MAC_MLS_TYPE_LOW, 0);
-	mac_mls_set_range(&cred->cr_label, MAC_MLS_TYPE_LOW, 0,
-	    MAC_MLS_TYPE_HIGH, 0);
+	SLOT(label) = mls_alloc(M_WAITOK);
 }
 
 static void
-mac_mls_create_subject(struct ucred *cred_parent, struct ucred *cred_child)
+mac_mls_init_ipq(struct ipq *ipq, struct label *label)
 {
 
-	mac_mls_copy_label(&cred_parent->cr_label, &cred_child->cr_label);
+	SLOT(label) = mls_alloc(M_WAITOK);
 }
 
 static int
-mac_mls_cred_check_relabel_subject(struct ucred *cred, struct mac *newlabel)
+mac_mls_init_mbuf(struct mbuf *mbuf, int how, struct label *label)
 {
-	int error, privilege_needed;
-	error = mac_mls_label_valid(newlabel);
-	if (error)
-		return (error);
-	/* Require both range and single entries for subjects. */
-	if ((newlabel->m_mls.mm_flags & MAC_MLS_FLAGS_BOTH) !=
-	    MAC_MLS_FLAGS_BOTH)
-		return (EINVAL);
-	/*
-	 * Accept the change if:
-	 * o Range is the same as current range.
-	 * o Single is in the current range.
-	 */
-	privilege_needed = 0;
-	if (!mac_mls_element_equal(&cred->cr_label.m_mls.mm_rangehigh,
-	    &newlabel->m_mls.mm_rangehigh))
-		privilege_needed = 1;
-	if (!mac_mls_element_equal(&cred->cr_label.m_mls.mm_rangelow,
-	    &newlabel->m_mls.mm_rangelow))
-		privilege_needed = 1;
-	if (!mac_mls_single_in_range(newlabel, &cred->cr_label))
-		privilege_needed = 1;
-	if (privilege_needed) {
-		error = suser_cred(cred, 0);
-		if (error)
-			return (error);
-	}
+
+	SLOT(label) = mls_alloc(how);
+	if (SLOT(label) == NULL)
+		return (ENOMEM);
+
 	return (0);
 }
 
-static int
-mac_mls_cred_check_relabel_vnode(struct ucred *cred, struct vnode *vp,
-    struct mac *oldlabel, struct mac *newlabel)
+static void
+mac_mls_init_mount(struct mount *mount, struct label *mntlabel,
+    struct label *fslabel)
+{
+
+	SLOT(mntlabel) = mls_alloc(M_WAITOK);
+	SLOT(fslabel) = mls_alloc(M_WAITOK);
+}
+
+static void
+mac_mls_init_socket(struct socket *socket, struct label *label,
+    struct label *peerlabel)
+{
+
+	SLOT(label) = mls_alloc(M_WAITOK);
+	SLOT(peerlabel) = mls_alloc(M_WAITOK);
+}
+
+static void
+mac_mls_init_subject(struct ucred *ucred, struct label *label)
+{
+
+	SLOT(label) = mls_alloc(M_WAITOK);
+}
+
+static void
+mac_mls_init_temp(struct label *label)
+{
+
+	SLOT(label) = mls_alloc(M_WAITOK);
+}
+
+static void
+mac_mls_init_vnode(struct vnode *vp, struct label *label)
+{
+
+	SLOT(label) = mls_alloc(M_WAITOK);
+}
+
+static void
+mac_mls_destroy_bpfdesc(struct bpf_d *bpf_d, struct label *label)
+{
+
+	mls_free(SLOT(label));
+	SLOT(label) = NULL;
+}
+
+static void
+mac_mls_destroy_devfsdirent(struct devfs_dirent *devfs_dirent,
+    struct label *label)
+{
+
+	mls_free(SLOT(label));
+	SLOT(label) = NULL;
+}
+
+static void
+mac_mls_destroy_ifnet(struct ifnet *ifnet, struct label *label)
+{
+
+	mls_free(SLOT(label));
+	SLOT(label) = NULL;
+}
+
+static void
+mac_mls_destroy_ipq(struct ipq *ipq, struct label *label)
+{
+
+	mls_free(SLOT(label));
+	SLOT(label) = NULL;
+}
+
+static void
+mac_mls_destroy_mbuf(struct mbuf *mbuf, struct label *label)
 {
-	int error, privilege_needed;
 
-	error = mac_mls_label_valid(newlabel);
-	if (error)
-		return (error);
-	/* Only single labels for vnodes. */
-	if ((newlabel->m_mls.mm_flags & MAC_MLS_FLAGS_BOTH) !=
-	    MAC_MLS_FLAG_SINGLE)
-		return (EINVAL);
-	/*
-	 * Accept the change if:
-	 * o Old label is in the current subject range.
-	 * o New label is in the current subject range.
-	 */
-	privilege_needed = 0;
-	if (!(mac_mls_single_in_range(oldlabel, &cred->cr_label)))
-		privilege_needed = 1;
-	if (!(mac_mls_single_in_range(newlabel, &cred->cr_label)))
-		privilege_needed = 1;
-	if (privilege_needed) {
-		error = suser_cred(cred, 0);
-		if (error)
-			return (error);
-	}
-	return (0);
+	mls_free(SLOT(label));
+	SLOT(label) = NULL;
 }
 
 static void
-mac_mls_relabel_subject(struct ucred *cred, struct mac *newlabel)
+mac_mls_destroy_mount(struct mount *mount, struct label *mntlabel,
+    struct label *fslabel)
 {
 
-	mac_mls_copy_label(newlabel, &cred->cr_label);
+	mls_free(SLOT(mntlabel));
+	SLOT(mntlabel) = NULL;
+	mls_free(SLOT(fslabel));
+	SLOT(fslabel) = NULL;
 }
 
-static int
-mac_mls_ifnet_check_send_mbuf(struct ifnet *ifnet, struct mbuf *m)
+static void
+mac_mls_destroy_socket(struct socket *socket, struct label *label,
+    struct label *peerlabel)
 {
 
-	if (!mac_mls_enabled)
-		return (0);
-	if (mac_mls_single_in_range(&m->m_pkthdr.label, &ifnet->if_label))
-		return (0);
-	else
-		return (EPERM);
+	mls_free(SLOT(label));
+	SLOT(label) = NULL;
+	mls_free(SLOT(peerlabel));
+	SLOT(peerlabel) = NULL;
 }
 
-static int
-mac_mls_bpfdesc_check_receive_from_ifnet(struct bpf_d *bpf_d,
-    struct ifnet *ifnet)
+static void
+mac_mls_destroy_subject(struct ucred *ucred, struct label *label)
 {
 
-	if (!mac_mls_enabled)
-		return (0);
-	if (mac_mls_single_equal(&bpf_d->bd_label, &ifnet->if_label))
-		return (0);
-	else
-		return (EPERM);
+	mls_free(SLOT(label));
+	SLOT(label) = NULL;
 }
 
-static int
-mac_mls_socket_check_receive_mbuf(struct socket *so, struct mbuf *m)
+static void
+mac_mls_destroy_temp(struct label *label)
 {
 
-	if (!mac_mls_enabled)
-		return (0);
-	if (mac_mls_single_equal(&so->so_label, &m->m_pkthdr.label))
-		return (0);
-	else
-		return (EPERM);
+	mls_free(SLOT(label));
+	SLOT(label) = NULL;
 }
 
 static void
-mac_mls_create_ifnet(struct ifnet *ifnet)
+mac_mls_destroy_vnode(struct vnode *vp, struct label *label)
+{
+
+	mls_free(SLOT(label));
+	SLOT(label) = NULL;
+}
+
+static int
+mac_mls_externalize(struct label *label, struct mac *extmac)
 {
-	int interface_label_type;
+	struct mac_mls *mac_mls;
+
+	mac_mls = SLOT(label);
+
+	if (mac_mls == NULL) {
+		printf("mac_mls_externalize: NULL pointer\n");
+		return (0);
+	}
+
+	extmac->m_mls = *mac_mls;
 
-	if (ifnet->if_type == IFT_LOOP)
-		interface_label_type = MAC_MLS_TYPE_EQUAL;
-	else
-		interface_label_type = MAC_MLS_TYPE_LOW;
-	mac_mls_init_label(&ifnet->if_label);
-	mac_mls_set_single(&ifnet->if_label, interface_label_type, 0);
-	mac_mls_set_range(&ifnet->if_label, interface_label_type, 0,
-	    interface_label_type, 0);
+	return (0);
 }
 
 static int
-mac_mls_cred_check_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
-    struct mac *newlabel)
+mac_mls_internalize(struct label *label, struct mac *extmac)
 {
+	struct mac_mls *mac_mls;
 	int error;
 
-	error = mac_mls_label_valid(newlabel);
+	mac_mls = SLOT(label);
+
+	error = mac_mls_valid(mac_mls);
 	if (error)
 		return (error);
-	/* Require both single and range for interfaces. */
-	if ((newlabel->m_mls.mm_flags & MAC_MLS_FLAGS_BOTH) !=
-	    MAC_MLS_FLAGS_BOTH)
-		return (EINVAL);
-	return (suser_cred(cred, 0));
+
+	*mac_mls = extmac->m_mls;
+
+	return (0);
 }
 
+/*
+ * Labeling event operations: file system objects, and things that look
+ * a lot like file system objects.
+ */
 static void
-mac_mls_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
-    struct mac *newlabel)
+mac_mls_create_devfs_device(dev_t dev, struct devfs_dirent *devfs_dirent,
+    struct label *label)
 {
+	struct mac_mls *mac_mls;
+	int mls_type;
 
-	mac_mls_copy_label(newlabel, &ifnet->if_label);
+	mac_mls = SLOT(label);
+	if (strcmp(dev->si_name, "null") == 0 ||
+	    strcmp(dev->si_name, "zero") == 0 ||
+	    strcmp(dev->si_name, "random") == 0 ||
+	    strncmp(dev->si_name, "fd/", strlen("fd/")) == 0)
+		mls_type = MAC_MLS_TYPE_EQUAL;
+	else if (strcmp(dev->si_name, "kmem") == 0 ||
+	    strcmp(dev->si_name, "mem") == 0)
+		mls_type = MAC_MLS_TYPE_HIGH;
+	else
+		mls_type = MAC_MLS_TYPE_LOW;
+	mac_mls_set_single(mac_mls, mls_type, 0);
 }
 
 static void
-mac_mls_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d)
+mac_mls_create_devfs_directory(char *dirname, int dirnamelen,
+    struct devfs_dirent *devfs_dirent, struct label *label)
 {
+	struct mac_mls *mac_mls;
 
-	mac_mls_init_label(&bpf_d->bd_label);
-	mac_mls_copy_single(&cred->cr_label, &bpf_d->bd_label);
+	mac_mls = SLOT(label);
+	mac_mls_set_single(mac_mls, MAC_MLS_TYPE_HIGH, 0);
 }
 
 static void
-mac_mls_create_mbuf_datagram_from_mbuf_fragmentqueue(
-    struct mbuf *fragmentqueue, struct mbuf *datagram)
+mac_mls_create_devfs_vnode(struct devfs_dirent *devfs_dirent,
+    struct label *direntlabel, struct vnode *vp, struct label *vnodelabel)
 {
+	struct mac_mls *source, *dest;
 
-	mac_mls_init_label(&datagram->m_pkthdr.label);
-	mac_mls_copy_single(&fragmentqueue->m_pkthdr.label,
-	    &datagram->m_pkthdr.label);
+	source = SLOT(direntlabel);
+	dest = SLOT(vnodelabel);
+	mac_mls_copy_single(source, dest);
 }
 
 static void
-mac_mls_create_mbuf_fragment_from_mbuf(struct mbuf *mbuf,
-    struct mbuf *fragment)
+mac_mls_create_vnode_from_vnode(struct ucred *cred, struct vnode *parent,
+    struct label *parentlabel, struct vnode *child,
+    struct label *childlabel)
 {
+	struct mac_mls *source, *dest;
 
-	mac_mls_init_label(&fragment->m_pkthdr.label);
-	mac_mls_copy_single(&mbuf->m_pkthdr.label, &fragment->m_pkthdr.label);
+	source = SLOT(&cred->cr_label);
+	dest = SLOT(childlabel);
+
+	mac_mls_copy_single(source, dest);
 }
 
 static void
-mac_mls_create_mbuf_fragmentqueue_from_mbuf_fragment(struct mbuf *fragment,
-    struct mbuf *fragmentqueue)
+mac_mls_create_mount(struct ucred *cred, struct mount *mp,
+    struct label *mntlabel, struct label *fslabel)
 {
+	struct mac_mls *source, *dest;
 
-	mac_mls_init_label(&fragmentqueue->m_pkthdr.label);
-	mac_mls_copy_single(&fragment->m_pkthdr.label,
-	    &fragmentqueue->m_pkthdr.label);
+	source = SLOT(&cred->cr_label);
+	dest = SLOT(mntlabel);
+	mac_mls_copy_single(source, dest);
+	dest = SLOT(fslabel);
+	mac_mls_copy_single(source, dest);
 }
 
 static void
-mac_mls_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf)
+mac_mls_create_root_mount(struct ucred *cred, struct mount *mp,
+    struct label *mntlabel, struct label *fslabel)
 {
+	struct mac_mls *mac_mls;
 
-	mac_mls_init_label(&newmbuf->m_pkthdr.label);
-	mac_mls_copy_single(&oldmbuf->m_pkthdr.label,
-	    &newmbuf->m_pkthdr.label);
+	/* Always mount root as high integrity. */
+	mac_mls = SLOT(fslabel);
+	mac_mls_set_single(mac_mls, MAC_MLS_TYPE_LOW, 0);
+	mac_mls = SLOT(mntlabel);
+	mac_mls_set_single(mac_mls, MAC_MLS_TYPE_LOW, 0);
 }
 
 static void
-mac_mls_create_mbuf_linklayer_for_ifnet(struct ifnet *ifnet,
-    struct mbuf *mbuf)
+mac_mls_relabel_vnode(struct ucred *cred, struct vnode *vp,
+    struct label *vnodelabel, struct label *label)
 {
+	struct mac_mls *source, *dest;
 
-	mac_mls_init_label(&mbuf->m_pkthdr.label);
-	mac_mls_set_single(&mbuf->m_pkthdr.label, MAC_MLS_TYPE_EQUAL, 0);
+	source = SLOT(label);
+	dest = SLOT(vnodelabel);
+
+	mac_mls_copy_single(source, dest);
 }
 
 static void
-mac_mls_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *m)
+mac_mls_update_devfsdirent_from_vnode(struct devfs_dirent *devfs_dirent,
+    struct label *direntlabel, struct vnode *vp, struct label *vnodelabel)
 {
+	struct mac_mls *source, *dest;
 
-	mac_mls_init_label(&m->m_pkthdr.label);
-	mac_mls_copy_single(&ifnet->if_label, &m->m_pkthdr.label);
+	source = SLOT(vnodelabel);
+	dest = SLOT(direntlabel);
+
+	mac_mls_copy_single(source, dest);
 }
 
 static void
-mac_mls_create_mbuf_multicast_encap_from_mbuf(struct mbuf *oldmbuf,
-    struct ifnet *ifnet, struct mbuf *newmbuf)
+mac_mls_update_procfsvnode_from_subject(struct vnode *vp,
+    struct label *vnodelabel, struct ucred *cred)
 {
+	struct mac_mls *source, *dest;
 
-	mac_mls_init_label(&newmbuf->m_pkthdr.label);
-	mac_mls_copy_single(&oldmbuf->m_pkthdr.label,
-	    &newmbuf->m_pkthdr.label);
+	source = SLOT(&cred->cr_label);
+	dest = SLOT(vnodelabel);
+
+	/*
+	 * Only copy the single, not the range, since vnodes only have
+	 * a single.
+	 */
+	mac_mls_copy_single(source, dest);
 }
 
 static void
-mac_mls_create_mbuf_netlayer_from_mbuf(struct mbuf *oldmbuf,
-    struct mbuf *newmbuf)
+mac_mls_update_vnode_from_externalized(struct vnode *vp,
+    struct label *vnodelabel, struct mac *extmac)
 {
+	struct mac_mls *source, *dest;
 
-	mac_mls_init_label(&newmbuf->m_pkthdr.label);
-	mac_mls_copy_single(&oldmbuf->m_pkthdr.label,
-	    &newmbuf->m_pkthdr.label);
+	/* XXX: Validity check. */
+	source = &extmac->m_mls;
+	dest = SLOT(vnodelabel);
+
+	mac_mls_copy_single(source, dest);
 }
 
-static int
-mac_mls_mbuf_fragment_matches_mbuf_fragmentqueue(struct mbuf *fragment,
-    struct mbuf *fragmentqueue)
+static void
+mac_mls_update_vnode_from_mount(struct vnode *vp, struct label *vnodelabel,
+    struct mount *mp, struct label *fslabel)
 {
+	struct mac_mls *source, *dest;
+
+	source = SLOT(fslabel);
+	dest = SLOT(vnodelabel);
 
-	return (mac_mls_single_equal(&fragment->m_pkthdr.label,
-	    &fragmentqueue->m_pkthdr.label));
+	mac_mls_copy_single(source, dest);
 }
 
+/*
+ * Labeling event operations: IPC object.
+ */
 static void
-mac_mls_create_mbuf_from_socket(struct socket *so, struct mbuf *m)
+mac_mls_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
+    struct mbuf *m, struct label *mbuflabel)
 {
+	struct mac_mls *source, *dest;
+
+	source = SLOT(socketlabel);
+	dest = SLOT(mbuflabel);
 
-	mac_mls_init_label(&m->m_pkthdr.label);
-	mac_mls_copy_single(&so->so_label, &m->m_pkthdr.label);
+	mac_mls_copy_single(source, dest);
 }
 

>>> TRUNCATED FOR MAIL (1000 lines) <<<

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?200206020342.g523glD82295>