PERFORCE change 19661 for review

Adam Migus amigus at freebsd.org
Sat Oct 19 23:59:06 GMT 2002


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

Change 19661 by amigus at amigus_ganyopa on 2002/10/19 16:58:28

	Biba compartments.  Exactly the same as MLS compartments.

Affected files ...

.. //depot/projects/trustedbsd/mac/sys/security/mac_biba/mac_biba.c#136 edit
.. //depot/projects/trustedbsd/mac/sys/security/mac_biba/mac_biba.h#6 edit
.. //depot/projects/trustedbsd/mac/sys/sys/mac.h#182 edit

Differences ...

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

@@ -102,23 +102,36 @@
     trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba");
 TUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces,
     sizeof(trusted_interfaces));
+static int	max_compartments = MAC_BIBA_MAX_COMPARTMENTS;
+SYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD,
+    &max_compartments, 0, "Maximum supported compartments");
 
-static int	mac_biba_ptys_equal = 0;
+static int	ptys_equal = 0;
 SYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW,
-    &mac_biba_ptys_equal, 0, "Label pty devices as biba/equal on create");
-TUNABLE_INT("security.mac.biba.ptys_equal", &mac_biba_ptys_equal);
+    &ptys_equal, 0, "Label pty devices as biba/equal on create");
+TUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal);
 
-static int	mac_biba_revocation_enabled = 0;
+static int	revocation_enabled = 0;
 SYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW,
-    &mac_biba_revocation_enabled, 0, "Revoke access to objects on relabel");
+    &revocation_enabled, 0, "Revoke access to objects on relabel");
 TUNABLE_INT("security.mac.biba.revocation_enabled",
-    &mac_biba_revocation_enabled);
+    &revocation_enabled);
 
 static int	mac_biba_slot;
 #define	SLOT(l)	((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr)
 
 MALLOC_DEFINE(M_MACBIBA, "biba label", "MAC/Biba labels");
 
+static __inline int
+biba_bit_set_empty(u_char *set) {
+		int i;
+
+		for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++)
+			if (set[i] != 0)
+				return (0);
+		return (1);
+}
+
 static struct mac_biba *
 biba_alloc(int flag)
 {
@@ -152,6 +165,7 @@
 mac_biba_dominate_element(struct mac_biba_element *a,
     struct mac_biba_element *b)
 {
+	int bit;
 
 	switch(a->mbe_type) {
 	case MAC_BIBA_TYPE_EQUAL:
@@ -182,6 +196,11 @@
 			return (0);
 
 		case MAC_BIBA_TYPE_GRADE:
+			for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++)
+				if (!MAC_BIBA_BIT_TEST(bit,
+				    a->mbe_compartments) &&
+				    MAC_BIBA_BIT_TEST(bit, b->mbe_compartments))
+					return (0);
 			return (a->mbe_grade >= b->mbe_grade);
 
 		default:
@@ -282,21 +301,21 @@
 	    MAC_BIBA_FLAGS_BOTH,
 	    ("mac_biba_subject_equal_ok: subject doesn't have both labels"));
 
-	/* If the single is EQUAL, it's ok */
+	/* If the single is EQUAL, it's ok. */
 	if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL)
 		return (0);
 
-	/* If either range endpoint is EQUAL, it's ok */
+	/* If either range endpoint is EQUAL, it's ok. */
 	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL ||
 	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
 		return (0);
 
-	/* If the range is low-high, it's ok */
+	/* If the range is low-high, it's ok. */
 	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW &&
 	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH)
 		return (0);
 
-	/* It's not OK. */
+	/* It's not ok. */
 	return (EPERM);
 }
 
@@ -312,7 +331,9 @@
 		case MAC_BIBA_TYPE_EQUAL:
 		case MAC_BIBA_TYPE_HIGH:
 		case MAC_BIBA_TYPE_LOW:
-			if (mac_biba->mb_single.mbe_grade != 0)
+			if (mac_biba->mb_single.mbe_grade != 0 ||
+			    !MAC_BIBA_BIT_SET_EMPTY(
+			    mac_biba->mb_single.mbe_compartments))
 				return (EINVAL);
 			break;
 
@@ -332,7 +353,9 @@
 		case MAC_BIBA_TYPE_EQUAL:
 		case MAC_BIBA_TYPE_HIGH:
 		case MAC_BIBA_TYPE_LOW:
-			if (mac_biba->mb_rangelow.mbe_grade != 0)
+			if (mac_biba->mb_rangelow.mbe_grade != 0 ||
+			    !MAC_BIBA_BIT_SET_EMPTY(
+			    mac_biba->mb_rangelow.mbe_compartments))
 				return (EINVAL);
 			break;
 
@@ -347,7 +370,9 @@
 		case MAC_BIBA_TYPE_EQUAL:
 		case MAC_BIBA_TYPE_HIGH:
 		case MAC_BIBA_TYPE_LOW:
-			if (mac_biba->mb_rangehigh.mbe_grade != 0)
+			if (mac_biba->mb_rangehigh.mbe_grade != 0 ||
+			    !MAC_BIBA_BIT_SET_EMPTY(
+			    mac_biba->mb_rangehigh.mbe_compartments))
 				return (EINVAL);
 			break;
 
@@ -368,33 +393,54 @@
 
 static void
 mac_biba_set_range(struct mac_biba *mac_biba, u_short typelow,
-    u_short gradelow, u_short typehigh, u_short gradehigh)
+    u_short gradelow, u_char *compartmentslow, u_short typehigh,
+    u_short gradehigh, u_char *compartmentshigh)
 {
 
 	mac_biba->mb_rangelow.mbe_type = typelow;
 	mac_biba->mb_rangelow.mbe_grade = gradelow;
+	if (compartmentslow)
+		memcpy(mac_biba->mb_rangelow.mbe_compartments, compartmentslow,
+		    sizeof(mac_biba->mb_rangelow.mbe_compartments));
 	mac_biba->mb_rangehigh.mbe_type = typehigh;
 	mac_biba->mb_rangehigh.mbe_grade = gradehigh;
+	if (compartmentshigh)
+		memcpy(mac_biba->mb_rangehigh.mbe_compartments,
+		    compartmentshigh,
+		    sizeof(mac_biba->mb_rangehigh.mbe_compartments));
 	mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
 }
 
 static void
-mac_biba_set_single(struct mac_biba *mac_biba, u_short type, u_short grade)
+mac_biba_set_single(struct mac_biba *mac_biba, u_short type, u_short grade,
+    u_char *compartments)
 {
 
 	mac_biba->mb_single.mbe_type = type;
 	mac_biba->mb_single.mbe_grade = grade;
+	if (compartments)
+		memcpy(mac_biba->mb_single.mbe_compartments, compartments,
+		    sizeof(mac_biba->mb_single.mbe_compartments));
 	mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
 }
 
 static void
 mac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto)
 {
+
 	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
 	    ("mac_biba_copy_range: labelfrom not range"));
 
+	memcpy(labelto->mb_rangelow.mbe_compartments,
+	    labelfrom->mb_rangelow.mbe_compartments,
+	    sizeof(labelfrom->mb_rangelow.mbe_compartments));
 	labelto->mb_rangelow = labelfrom->mb_rangelow;
+
+	memcpy(labelto->mb_rangehigh.mbe_compartments,
+	    labelfrom->mb_rangehigh.mbe_compartments,
+	    sizeof(labelfrom->mb_rangehigh.mbe_compartments));
 	labelto->mb_rangehigh = labelfrom->mb_rangehigh;
+
 	labelto->mb_flags |= MAC_BIBA_FLAG_RANGE;
 }
 
@@ -405,6 +451,9 @@
 	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
 	    ("mac_biba_copy_single: labelfrom not single"));
 
+	memcpy(labelto->mb_single.mbe_compartments,
+	    labelfrom->mb_single.mbe_compartments,
+	    sizeof(labelfrom->mb_single.mbe_compartments));
 	labelto->mb_single = labelfrom->mb_single;
 	labelto->mb_flags |= MAC_BIBA_FLAG_SINGLE;
 }
@@ -472,6 +521,7 @@
 mac_biba_element_to_string(char *string, size_t size,
     struct mac_biba_element *element)
 {
+	int pos, bit = 1;
 
 	switch (element->mbe_type) {
 	case MAC_BIBA_TYPE_HIGH:
@@ -484,7 +534,15 @@
 		return (snprintf(string, size, "equal"));
 
 	case MAC_BIBA_TYPE_GRADE:
-		return (snprintf(string, size, "%d", element->mbe_grade));
+		pos = snprintf(string, size, "%d:", element->mbe_grade);
+		for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) {
+			if (MAC_BIBA_BIT_TEST(bit, element->mbe_compartments))
+				pos += snprintf(string + pos, size - pos,
+				    "%d+", bit);
+		}
+		if (string[pos - 1] == '+' || string[pos - 1] == ':')
+			string[--pos] = NULL;
+		return (pos);
 
 	default:
 		panic("mac_biba_element_to_string: invalid type (%d)",
@@ -605,13 +663,39 @@
 		element->mbe_type = MAC_BIBA_TYPE_EQUAL;
 		element->mbe_grade = MAC_BIBA_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->mbe_type = MAC_BIBA_TYPE_GRADE;
 		element->mbe_grade = 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_BIBA_MAX_COMPARTMENTS)
+				return (EINVAL);
+
+			MAC_BIBA_BIT_SET(d, element->mbe_compartments); 
+
+			if (*p1 == '\0')
+				break;
+			if (p1 == p0 || *p1 != '+')
+				return (EINVAL);
+		}
 	}
 
 	return (0);
@@ -624,7 +708,7 @@
 static int
 mac_biba_parse(struct mac_biba *mac_biba, char *string)
 {
-	char *single, *range, *rangeend, *rangehigh, *rangelow;
+	char *range, *rangeend, *rangehigh, *rangelow, *single;
 	int error;
 
 	/* Do we have a range? */
@@ -670,7 +754,7 @@
 		    rangelow);
 		if (error)
 			return (error);
-		error == mac_biba_parse_element(&mac_biba->mb_rangehigh,
+		error = mac_biba_parse_element(&mac_biba->mb_rangehigh,
 		    rangehigh);
 		if (error)
 			return (error);
@@ -730,13 +814,16 @@
 	    strcmp(dev->si_name, "random") == 0 ||
 	    strncmp(dev->si_name, "fd/", strlen("fd/")) == 0)
 		biba_type = MAC_BIBA_TYPE_EQUAL;
-	else if (mac_biba_ptys_equal &&
+	else if (strcmp(dev->si_name, "kmem") == 0 ||
+	    strcmp(dev->si_name, "mem") == 0)
+		biba_type = MAC_BIBA_TYPE_HIGH;
+	else if (ptys_equal &&
 	    (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
 	    strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
 		biba_type = MAC_BIBA_TYPE_EQUAL;
 	else
 		biba_type = MAC_BIBA_TYPE_HIGH;
-	mac_biba_set_single(mac_biba, biba_type, 0);
+	mac_biba_set_single(mac_biba, biba_type, 0, NULL);
 }
 
 static void
@@ -746,7 +833,7 @@
 	struct mac_biba *mac_biba;
 
 	mac_biba = SLOT(label);
-	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0);
+	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
 }
 
 static void
@@ -805,9 +892,9 @@
 
 	/* Always mount root as high integrity. */
 	mac_biba = SLOT(fslabel);
-	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0);
+	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
 	mac_biba = SLOT(mntlabel);
-	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0);
+	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
 }
 
 static void
@@ -1044,14 +1131,20 @@
 					break;
 				}
 			}
+			else {
+				*p = '\0';
+				printf("MAC/Biba warning: interface name "
+				    "\"%s\" is too long (must be < %d)\n",
+				    q, IFNAMSIZ);
+			}
 			if (*p == '\0')
 				break;
 			q = p + 1;
 		}
 	}
 set:
-	mac_biba_set_single(dest, grade, 0);
-	mac_biba_set_range(dest, grade, 0, grade, 0);
+	mac_biba_set_single(dest, grade, 0, NULL);
+	mac_biba_set_range(dest, grade, 0, NULL, grade, 0, NULL);
 }
 
 static void
@@ -1120,7 +1213,7 @@
 
 	dest = SLOT(mbuflabel);
 
-	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0);
+	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
 }
 
 static void
@@ -1249,8 +1342,9 @@
 
 	dest = SLOT(&cred->cr_label);
 
-	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0);
-	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, MAC_BIBA_TYPE_HIGH, 0);
+	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
+	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, MAC_BIBA_TYPE_HIGH,
+	    0, NULL);
 }
 
 static void
@@ -1260,8 +1354,9 @@
 
 	dest = SLOT(&cred->cr_label);
 
-	mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0);
-	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, MAC_BIBA_TYPE_HIGH, 0);
+	mac_biba_set_single(dest, MAC_BIBA_TYPE_LOW, 0, NULL);
+	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, MAC_BIBA_TYPE_HIGH,
+	    0, NULL);
 }
 
 static void
@@ -1333,7 +1428,7 @@
 			return (EPERM);
 
 		/*
-		 * To have EQUAL in any components of the new credential
+		 * To have EQUAL in any component of the new credential
 		 * Biba label, the subject must already have EQUAL in
 		 * their label.
 		 */
@@ -1395,12 +1490,17 @@
 	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
 		/*
 		 * Rely on the traditional superuser status for the Biba
-		 * interface relabel requirements. XXXMAC: This will go
+		 * interface relabel requirements.  XXXMAC: This will go
 		 * away.
 		 */
 		error = suser_cred(cred, 0);
 		if (error)
 			return (EPERM);
+
+		/*
+		 * XXXMAC: Additional consistency tests regarding the single
+		 * and the range of the new label might be performed here.
+		 */
 	}
 
 	return (0);
@@ -1521,7 +1621,7 @@
 		/*
 		 * To change the Biba label on a pipe, the new pipe label
 		 * must be in the subject range.
-	 	 */
+		 */
 		if (!mac_biba_single_in_range(new, subj))
 			return (EPERM);
 
@@ -1707,6 +1807,9 @@
 {
 	struct mac_biba *subj, *obj;
 
+	if (!mac_biba_enabled)
+		return (0);
+
 	subj = SLOT(&cred->cr_label);
 	obj = SLOT(socketlabel);
 
@@ -1918,7 +2021,7 @@
 	 * Rely on the use of open()-time protections to handle
 	 * non-revocation cases.
 	 */
-	if (!mac_biba_enabled || !mac_biba_revocation_enabled)
+	if (!mac_biba_enabled || !revocation_enabled)
 		return (0);
 
 	subj = SLOT(&cred->cr_label);
@@ -1967,7 +2070,7 @@
 {
 	struct mac_biba *subj, *obj;
 
-	if (!mac_biba_enabled || !mac_biba_revocation_enabled)
+	if (!mac_biba_enabled || !revocation_enabled)
 		return (0);
 
 	subj = SLOT(&active_cred->cr_label);
@@ -1985,7 +2088,7 @@
 {
 	struct mac_biba *subj, *obj;
 
-	if (!mac_biba_enabled || !mac_biba_revocation_enabled)
+	if (!mac_biba_enabled || !revocation_enabled)
 		return (0);
 
 	subj = SLOT(&active_cred->cr_label);
@@ -2067,8 +2170,7 @@
 		 * To change the Biba label on a vnode, the new vnode label
 		 * must be in the subject range.
 		 */
-		if (new->mb_flags & MAC_BIBA_FLAG_SINGLE &&
-		    !mac_biba_single_in_range(new, subj))
+		if (!mac_biba_single_in_range(new, subj))
 			return (EPERM);
 
 		/*
@@ -2288,7 +2390,7 @@
 {
 	struct mac_biba *subj, *obj;
 
-	if (!mac_biba_enabled || !mac_biba_revocation_enabled)
+	if (!mac_biba_enabled || !revocation_enabled)
 		return (0);
 
 	subj = SLOT(&active_cred->cr_label);
@@ -2563,3 +2665,4 @@
 
 MAC_POLICY_SET(mac_biba_ops, trustedbsd_mac_biba, "TrustedBSD MAC/Biba",
     MPC_LOADTIME_FLAG_NOTLATE, &mac_biba_slot);
+

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

@@ -68,9 +68,13 @@
  * and mb_grade represents the hierarchal grade if valid for the current
  * mb_type.
  */
+
+#define	MAC_BIBA_MAX_COMPARTMENTS	256
+
 struct mac_biba_element {
 	u_short	mbe_type;
 	u_short	mbe_grade;
+	u_char	mbe_compartments[MAC_BIBA_MAX_COMPARTMENTS >> 3];
 };
 
 /*
@@ -86,4 +90,13 @@
 };
 #endif
 
+/*
+ * Biba compartments bit test/set macros.
+ * The range is 1 to MAC_BIBA_MAX_COMPARTMENTS.
+ */
+#define	MAC_BIBA_BIT_TEST(b, w)	(w[((b - 1) >> 3)] & (1 << ((b - 1) & 7)))
+#define	MAC_BIBA_BIT_SET(b, w)	(w[((b - 1) >> 3)] |= (1 << ((b - 1) & 7)))
+#define MAC_BIBA_BIT_SET_EMPTY(set)	biba_bit_set_empty(set)
+
 #endif /* !_SYS_SECURITY_MAC_BIBA_H */
+

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

@@ -114,9 +114,12 @@
  * these can be disabled.
  */
 
+#define	MAC_BIBA_MAX_COMPARTMENTS	256
+
 struct mac_biba_element {
 	u_short	mbe_type;
 	u_short	mbe_grade;
+	u_char	mbe_compartments[MAC_BIBA_MAX_COMPARTMENTS >> 3];
 };
 
 struct mac_biba {
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