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