Date: Sat, 19 Oct 2002 16:59:06 -0700 (PDT) From: Adam Migus <amigus@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 19661 for review Message-ID: <200210192359.g9JNx6Zm095000@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=19661 Change 19661 by amigus@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@FreeBSD.org with "unsubscribe p4-projects" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200210192359.g9JNx6Zm095000>