Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 4 Oct 2002 14:10:58 -0700 (PDT)
From:      Adam Migus <amigus@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 18676 for review
Message-ID:  <200210042110.g94LAwkF056149@freefall.freebsd.org>

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

Change 18676 by amigus@amigus_ganymede on 2002/10/04 14:10:32

	An implementation of compartments for the MAC/MLS confidentiality
	policy.  The compartments are bits in a fixed sized bit set of size
	MAC_MLS_MAX_COMPARTMENTS which is declared in mac_mls.h.
	Elements of the label containing a level now take an additional
	string on the end of the form [:[i][,j][,...]] where i,j,... are
	numbers between 1 and MAC_MLS_MAX_COMPARTMENTS.
	The module is backward compatible in that if you specify a numeric
	level without a compartment list you are given that level with no
	compartments.  By virtue this is semantically identical to the
	old model.  LOW, HIGH and EQUAL also retain there original
	semantics and as such cannot be in any compartments.
	Eventually I will implement a userland mapping between symbolic
	names and compartment numbers.
	Please test/experiment and let me know if you have any questions
	or comments.

Affected files ...

.. //depot/projects/trustedbsd/mac/sys/security/mac_mls/mac_mls.c#104 edit
.. //depot/projects/trustedbsd/mac/sys/security/mac_mls/mac_mls.h#6 edit

Differences ...

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

@@ -103,6 +103,10 @@
 TUNABLE_INT("security.mac.mls.revocation_enabled",
     &mac_mls_revocation_enabled);
 
+static int	mac_mls_max_compartments = MAC_MLS_MAX_COMPARTMENTS;
+SYSCTL_INT(_security_mac_mls, OID_AUTO, max_compartments, CTLFLAG_RD,
+    &mac_mls_max_compartments, 0, "Maximum compartments the policy supports");
+
 static int	mac_mls_slot;
 #define	SLOT(l)	((struct mac_mls *)LABEL_TO_SLOT((l), mac_mls_slot).l_ptr)
 
@@ -145,6 +149,7 @@
 mac_mls_dominate_element(struct mac_mls_element *a,
     struct mac_mls_element *b)
 {
+	int bit;
 
 	switch(a->mme_type) {
 	case MAC_MLS_TYPE_EQUAL:
@@ -175,6 +180,11 @@
 			return (0);
 
 		case MAC_MLS_TYPE_LEVEL:
+			for (bit = 1; bit <= MAC_MLS_MAX_COMPARTMENTS; bit++)
+				if (!MAC_MLS_BIT_TEST(bit,
+				    a->mme_compartments) &&
+				    MAC_MLS_BIT_TEST(bit, b->mme_compartments))
+					return (0);
 			return (a->mme_level >= b->mme_level);
 
 		default:
@@ -304,7 +314,9 @@
 		case MAC_MLS_TYPE_EQUAL:
 		case MAC_MLS_TYPE_HIGH:
 		case MAC_MLS_TYPE_LOW:
-			if (mac_mls->mm_single.mme_level != 0)
+			if (mac_mls->mm_single.mme_level != 0 ||
+			    !MAC_MLS_BIT_SET_EMPTY(
+			    mac_mls->mm_single.mme_compartments))
 				return (EINVAL);
 			break;
 
@@ -324,7 +336,9 @@
 		case MAC_MLS_TYPE_EQUAL:
 		case MAC_MLS_TYPE_HIGH:
 		case MAC_MLS_TYPE_LOW:
-			if (mac_mls->mm_rangelow.mme_level != 0)
+			if (mac_mls->mm_rangelow.mme_level != 0 ||
+			    !MAC_MLS_BIT_SET_EMPTY(
+			    mac_mls->mm_rangelow.mme_compartments))
 				return (EINVAL);
 			break;
 
@@ -339,7 +353,9 @@
 		case MAC_MLS_TYPE_EQUAL:
 		case MAC_MLS_TYPE_HIGH:
 		case MAC_MLS_TYPE_LOW:
-			if (mac_mls->mm_rangehigh.mme_level != 0)
+			if (mac_mls->mm_rangehigh.mme_level != 0 ||
+			    !MAC_MLS_BIT_SET_EMPTY(
+			    mac_mls->mm_rangehigh.mme_compartments))
 				return (EINVAL);
 			break;
 
@@ -360,33 +376,53 @@
 
 static void
 mac_mls_set_range(struct mac_mls *mac_mls, u_short typelow,
-    u_short levellow, u_short typehigh, u_short levelhigh)
+    u_short levellow, u_char *compartmentslow, u_short typehigh,
+    u_short levelhigh, u_char *compartmentshigh)
 {
 
 	mac_mls->mm_rangelow.mme_type = typelow;
 	mac_mls->mm_rangelow.mme_level = levellow;
+	if (compartmentslow)
+		memcpy(mac_mls->mm_rangelow.mme_compartments, compartmentslow,
+		    sizeof(mac_mls->mm_rangelow.mme_compartments));
 	mac_mls->mm_rangehigh.mme_type = typehigh;
 	mac_mls->mm_rangehigh.mme_level = levelhigh;
+	if (compartmentshigh)
+		memcpy(mac_mls->mm_rangehigh.mme_compartments, compartmentshigh,
+		    sizeof(mac_mls->mm_rangehigh.mme_compartments));
 	mac_mls->mm_flags |= MAC_MLS_FLAG_RANGE;
 }
 
 static void
-mac_mls_set_single(struct mac_mls *mac_mls, u_short type, u_short level)
+mac_mls_set_single(struct mac_mls *mac_mls, u_short type, u_short level,
+    u_char *compartments)
 {
 
 	mac_mls->mm_single.mme_type = type;
 	mac_mls->mm_single.mme_level = level;
+	if (compartments)
+		memcpy(mac_mls->mm_single.mme_compartments, compartments,
+		    sizeof(mac_mls->mm_single.mme_compartments));
 	mac_mls->mm_flags |= MAC_MLS_FLAG_SINGLE;
 }
 
 static void
 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"));
 
+	memcpy(labelto->mm_rangelow.mme_compartments,
+	    labelfrom->mm_rangelow.mme_compartments,
+	    sizeof(labelfrom->mm_rangelow.mme_compartments));
 	labelto->mm_rangelow = labelfrom->mm_rangelow;
+
+	memcpy(labelto->mm_rangehigh.mme_compartments,
+	    labelfrom->mm_rangehigh.mme_compartments,
+	    sizeof(labelfrom->mm_rangehigh.mme_compartments));
 	labelto->mm_rangehigh = labelfrom->mm_rangehigh;
+
 	labelto->mm_flags |= MAC_MLS_FLAG_RANGE;
 }
 
@@ -397,7 +433,11 @@
 	KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_SINGLE) != 0,
 	    ("mac_mls_copy_single: labelfrom not single"));
 
+	memcpy(labelto->mm_single.mme_compartments,
+	    labelfrom->mm_single.mme_compartments,
+	    sizeof(labelfrom->mm_single.mme_compartments));
 	labelto->mm_single = labelfrom->mm_single;
+
 	labelto->mm_flags |= MAC_MLS_FLAG_SINGLE;
 }
 
@@ -464,6 +504,7 @@
 mac_mls_element_to_string(char *string, size_t size,
     struct mac_mls_element *element)
 {
+	int pos, bit = 1;
 
 	switch (element->mme_type) {
 	case MAC_MLS_TYPE_HIGH:
@@ -476,7 +517,15 @@
 		return (snprintf(string, size, "equal"));
 
 	case MAC_MLS_TYPE_LEVEL:
-		return (snprintf(string, size, "%d", element->mme_level));
+		pos = snprintf(string, size, "%d:", element->mme_level);
+		for (bit = 1; bit <= MAC_MLS_MAX_COMPARTMENTS; bit++) {
+			if (MAC_MLS_BIT_TEST(bit, element->mme_compartments))
+				pos += snprintf(string + pos, size - pos,
+				    "%d+", bit);
+		}
+		if (string[pos - 1] == '+' || string[pos - 1] == ':')
+			string[--pos] = NULL;
+		return (pos);
 
 	default:
 		panic("mac_mls_element_to_string: invalid type (%d)",
@@ -605,13 +654,39 @@
 		element->mme_type = MAC_MLS_TYPE_EQUAL;
 		element->mme_level = MAC_MLS_TYPE_UNDEF;
 	} else {
+		char *p0, *p1;
 		int d;
 
-		d = strtol(string, NULL, 10);
+		p0 = string;
+		d = strtol(p0, &p1, 10);
+	
 		if (d < 0 || d > 65535)
 			return (EINVAL);
 		element->mme_type = MAC_MLS_TYPE_LEVEL;
 		element->mme_level = d;
+
+		if (*p1 != ':')  {
+			if (p1 == p0 || *p1 != '\0')
+				return (EINVAL);
+			else
+				return (0);
+		}
+		else
+			if (*(p1 + 1) == '\0')
+				return (0);
+
+		while ((p0 = ++p1)) {
+			d = strtol(p0, &p1, 10);
+			if (d < 1 || d > MAC_MLS_MAX_COMPARTMENTS)
+				return (EINVAL);
+
+			MAC_MLS_BIT_SET(d, element->mme_compartments); 
+
+			if (*p1 == '\0')
+				break;
+			if (p1 == p0 || *p1 != '+')
+				return (EINVAL);
+		}
 	}
 
 	return (0);
@@ -747,7 +822,7 @@
 		mls_type = MAC_MLS_TYPE_EQUAL;
 	else
 		mls_type = MAC_MLS_TYPE_LOW;
-	mac_mls_set_single(mac_mls, mls_type, 0);
+	mac_mls_set_single(mac_mls, mls_type, 0, NULL);
 }
 
 static void
@@ -757,7 +832,7 @@
 	struct mac_mls *mac_mls;
 
 	mac_mls = SLOT(label);
-	mac_mls_set_single(mac_mls, MAC_MLS_TYPE_LOW, 0);
+	mac_mls_set_single(mac_mls, MAC_MLS_TYPE_LOW, 0, NULL);
 }
 
 static void
@@ -816,9 +891,9 @@
 
 	/* Always mount root as high integrity. */
 	mac_mls = SLOT(fslabel);
-	mac_mls_set_single(mac_mls, MAC_MLS_TYPE_LOW, 0);
+	mac_mls_set_single(mac_mls, MAC_MLS_TYPE_LOW, 0, NULL);
 	mac_mls = SLOT(mntlabel);
-	mac_mls_set_single(mac_mls, MAC_MLS_TYPE_LOW, 0);
+	mac_mls_set_single(mac_mls, MAC_MLS_TYPE_LOW, 0, NULL);
 }
 
 static void
@@ -1024,8 +1099,8 @@
 	else
 		level = MAC_MLS_TYPE_LOW;
 
-	mac_mls_set_single(dest, level, 0);
-	mac_mls_set_range(dest, level, 0, level, 0);
+	mac_mls_set_single(dest, level, 0, NULL);
+	mac_mls_set_range(dest, level, 0, NULL, level, 0, NULL);
 }
 
 static void
@@ -1094,7 +1169,7 @@
 
 	dest = SLOT(mbuflabel);
 
-	mac_mls_set_single(dest, MAC_MLS_TYPE_EQUAL, 0);
+	mac_mls_set_single(dest, MAC_MLS_TYPE_EQUAL, 0, NULL);
 }
 
 static void
@@ -1221,8 +1296,9 @@
 
 	dest = SLOT(&cred->cr_label);
 
-	mac_mls_set_single(dest, MAC_MLS_TYPE_EQUAL, 0);
-	mac_mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, MAC_MLS_TYPE_HIGH, 0);
+	mac_mls_set_single(dest, MAC_MLS_TYPE_EQUAL, 0, NULL);
+	mac_mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH,
+	    0, NULL);
 }
 
 static void
@@ -1232,8 +1308,9 @@
 
 	dest = SLOT(&cred->cr_label);
 
-	mac_mls_set_single(dest, MAC_MLS_TYPE_LOW, 0);
-	mac_mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, MAC_MLS_TYPE_HIGH, 0);
+	mac_mls_set_single(dest, MAC_MLS_TYPE_LOW, 0, NULL);
+	mac_mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH,
+	    0, NULL);
 }
 
 static void

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

@@ -66,11 +66,20 @@
  * Structures and constants associated with a Multi-Level Security policy.
  * mac_mls represents an MLS label, with mm_type determining its properties,
  * and mm_level represents the hierarchal sensitivity level if valid for the
- * current mm_type.
+ * current mm_type.  If compartments are used, the same semantics apply as
+ * long as the suject is in every compartment the object is in.  LOW, EQUAL
+ * and HIGH cannot be in compartments.
+ */
+
+/*
+ * MLS compartments bit set size (in bits).
  */
+#define	MAC_MLS_MAX_COMPARTMMENTS	256
+
 struct mac_mls_element {
 	u_short	mme_type;
 	u_short	mme_level;
+	u_char	mme_compartments[MAC_MLS_MAX_COMPARTMENTS >> 3];
 };
 
 /*
@@ -86,4 +95,20 @@
 };
 #endif
 
+/*
+ * MLS compartments bit test/set macros.
+ * The range is 1 to MAC_MLS_MAX_COMPARTMENTS.
+ */
+#define	MAC_MLS_BIT_TEST(b, w)	(w[((b - 1) >> 3)] & (1 << ((b - 1) & 7)))
+#define	MAC_MLS_BIT_SET(b, w)	(w[((b - 1) >> 3)] |= (1 << ((b - 1) & 7)))
+
+static __inline int
+MAC_MLS_BIT_SET_EMPTY(u_char *__set) {
+		int i;
+		for (i = 0; i < MAC_MLS_MAX_COMPARTMENTS >> 3; i++)
+			if (__set[i] != 0)
+				return (0);
+		return (1);
+}
+
 #endif /* !_SYS_SECURITY_MAC_MLS_H */

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?200210042110.g94LAwkF056149>