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