PERFORCE change 18676 for review
Adam Migus
amigus at freebsd.org
Fri Oct 4 21:10:58 GMT 2002
http://people.freebsd.org/~peter/p4db/chv.cgi?CH=18676
Change 18676 by amigus at 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 at trustedbsd.org
with "unsubscribe trustedbsd-cvs" in the body of the message
More information about the trustedbsd-cvs
mailing list