Fw: PERFORCE change 18676 for review
Adam Migus
adam at migus.org
Fri Oct 4 21:18:13 GMT 2002
All,
I've just submitted my implementation of compartments for the MAC/MLS
policy. The commit message below contains the details. If you have any
questions let me know. Please note: This increases the size of the label
in userland. Consequently, persistant label store will need to be
reinitialized.
Adam
----- Original Message -----
From: "Adam Migus" <amigus at freebsd.org>
To: "Perforce Change Reviews" <perforce at freebsd.org>
Sent: Friday, October 04, 2002 5:10 PM
Subject: PERFORCE change 18676 for review
> 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-discuss" in the body of the message
More information about the trustedbsd-discuss
mailing list