diff options
author | rwatson <rwatson@FreeBSD.org> | 2002-10-21 18:42:01 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2002-10-21 18:42:01 +0000 |
commit | 63323cc3aec332230923139e004f15a08fa171d1 (patch) | |
tree | 229228b753fcff46679f1fee5df00dfaf6292d68 /sys/security | |
parent | 54f5e2ef60254c34c2bb84b9948f7678ae758d31 (diff) | |
download | FreeBSD-src-63323cc3aec332230923139e004f15a08fa171d1.zip FreeBSD-src-63323cc3aec332230923139e004f15a08fa171d1.tar.gz |
Add compartment support to Biba and MLS policies. The logic of the
policies remains the same: subjects and objects are labeled for
integrity or sensitivity, and a dominance operator determines whether
or not subject/object accesses are permitted to limit inappropriate
information flow. Compartments are a non-hierarchal component to
the label, so add a bitfield to the label element for each, and a
set check as part of the dominance operator. This permits the
implementation of "need to know" elements of MLS.
Obtained from: TrustedBSD Project
Sponsored by: DARPA, Network Associates Laboratories
Diffstat (limited to 'sys/security')
-rw-r--r-- | sys/security/mac/mac_framework.h | 4 | ||||
-rw-r--r-- | sys/security/mac_biba/mac_biba.c | 74 | ||||
-rw-r--r-- | sys/security/mac_biba/mac_biba.h | 10 | ||||
-rw-r--r-- | sys/security/mac_mls/mac_mls.c | 74 | ||||
-rw-r--r-- | sys/security/mac_mls/mac_mls.h | 10 |
5 files changed, 140 insertions, 32 deletions
diff --git a/sys/security/mac/mac_framework.h b/sys/security/mac/mac_framework.h index 8a07849..4acf755 100644 --- a/sys/security/mac/mac_framework.h +++ b/sys/security/mac/mac_framework.h @@ -76,9 +76,11 @@ * mb_type. These structures will move to mac_biba.h once we have dymamic * labels exposed to userland. */ +#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]; }; /* @@ -100,9 +102,11 @@ struct mac_biba { * current mm_type. These structures will move to mac_mls.h once we have * dynamic labels exposed to userland. */ +#define MAC_MLS_MAX_COMPARTMENTS 256 struct mac_mls_element { u_short mme_type; u_short mme_level; + u_char mme_compartments[MAC_MLS_MAX_COMPARTMENTS >> 3]; }; /* diff --git a/sys/security/mac_biba/mac_biba.c b/sys/security/mac_biba/mac_biba.c index 0c3a474..027c2aa 100644 --- a/sys/security/mac_biba/mac_biba.c +++ b/sys/security/mac_biba/mac_biba.c @@ -102,6 +102,10 @@ SYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD, 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 ptys_equal = 0; SYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW, &ptys_equal, 0, "Label pty devices as biba/equal on create"); @@ -117,6 +121,16 @@ static int mac_biba_slot; 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) { @@ -150,6 +164,7 @@ static int 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: @@ -180,6 +195,11 @@ mac_biba_dominate_element(struct mac_biba_element *a, 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: @@ -310,7 +330,9 @@ mac_biba_valid(struct mac_biba *mac_biba) 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; @@ -330,7 +352,9 @@ mac_biba_valid(struct mac_biba *mac_biba) 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; @@ -345,7 +369,9 @@ mac_biba_valid(struct mac_biba *mac_biba) 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; @@ -366,28 +392,42 @@ mac_biba_valid(struct mac_biba *mac_biba) 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 != NULL) + 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 != NULL) + 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 != NULL) + 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")); @@ -508,7 +548,7 @@ mac_biba_create_devfs_device(dev_t dev, struct devfs_dirent *devfs_dirent, 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 @@ -518,7 +558,7 @@ mac_biba_create_devfs_directory(char *dirname, int dirnamelen, 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 @@ -577,9 +617,9 @@ mac_biba_create_root_mount(struct ucred *cred, struct mount *mp, /* 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 @@ -821,8 +861,8 @@ mac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) } } 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 @@ -883,7 +923,7 @@ mac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 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 @@ -1011,8 +1051,9 @@ mac_biba_create_proc0(struct ucred *cred) 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 @@ -1022,8 +1063,9 @@ mac_biba_create_proc1(struct ucred *cred) 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_HIGH, 0, NULL); + mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, + MAC_BIBA_TYPE_HIGH, 0, NULL); } static void diff --git a/sys/security/mac_biba/mac_biba.h b/sys/security/mac_biba/mac_biba.h index aa42344..9d6ce0f 100644 --- a/sys/security/mac_biba/mac_biba.h +++ b/sys/security/mac_biba/mac_biba.h @@ -58,4 +58,14 @@ #define MAC_BIBA_TYPE_EQUAL 4 /* Equivilent to any * MAC_BIBA_TYPE_LABEL. */ +/* + * 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 */ diff --git a/sys/security/mac_mls/mac_mls.c b/sys/security/mac_mls/mac_mls.c index d0a5073..d88181b 100644 --- a/sys/security/mac_mls/mac_mls.c +++ b/sys/security/mac_mls/mac_mls.c @@ -101,11 +101,25 @@ SYSCTL_INT(_security_mac_mls, OID_AUTO, revocation_enabled, CTLFLAG_RW, &revocation_enabled, 0, "Revoke access to objects on relabel"); TUNABLE_INT("security.mac.mls.revocation_enabled", &revocation_enabled); +static int max_compartments = MAC_MLS_MAX_COMPARTMENTS; +SYSCTL_INT(_security_mac_mls, OID_AUTO, max_compartments, CTLFLAG_RD, + &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) MALLOC_DEFINE(M_MACMLS, "mls label", "MAC/MLS labels"); +static __inline int +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); +} + static struct mac_mls * mls_alloc(int flag) { @@ -139,6 +153,7 @@ static int 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: @@ -169,6 +184,11 @@ mac_mls_dominate_element(struct mac_mls_element *a, 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: @@ -298,7 +318,9 @@ mac_mls_valid(struct mac_mls *mac_mls) 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; @@ -318,7 +340,9 @@ mac_mls_valid(struct mac_mls *mac_mls) 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; @@ -333,7 +357,9 @@ mac_mls_valid(struct mac_mls *mac_mls) 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; @@ -354,28 +380,42 @@ mac_mls_valid(struct mac_mls *mac_mls) 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 != NULL) + 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 != NULL) + 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 != NULL) + 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")); @@ -499,7 +539,7 @@ mac_mls_create_devfs_device(dev_t dev, struct devfs_dirent *devfs_dirent, 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 @@ -509,7 +549,7 @@ mac_mls_create_devfs_directory(char *dirname, int dirnamelen, 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 @@ -568,9 +608,9 @@ mac_mls_create_root_mount(struct ucred *cred, struct mount *mp, /* 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 @@ -776,8 +816,8 @@ mac_mls_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) 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 @@ -838,7 +878,7 @@ mac_mls_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 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 @@ -966,8 +1006,9 @@ mac_mls_create_proc0(struct ucred *cred) 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 @@ -977,8 +1018,9 @@ mac_mls_create_proc1(struct ucred *cred) 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 diff --git a/sys/security/mac_mls/mac_mls.h b/sys/security/mac_mls/mac_mls.h index bb99a36..bf255a1 100644 --- a/sys/security/mac_mls/mac_mls.h +++ b/sys/security/mac_mls/mac_mls.h @@ -58,4 +58,14 @@ #define MAC_MLS_TYPE_EQUAL 4 /* Equivilent to any * MAC_MLS_TYPE_LABEL. */ +/* + * 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))) +#define MAC_MLS_BIT_SET_EMPTY(set) mls_bit_set_empty(set) + #endif /* !_SYS_SECURITY_MAC_MLS_H */ |