Date: Sat, 1 Jun 2002 20:42:47 -0700 (PDT) From: Robert Watson <rwatson@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 12286 for review Message-ID: <200206020342.g523glD82295@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://people.freebsd.org/~peter/p4db/chv.cgi?CH=12286 Change 12286 by rwatson@rwatson_curry on 2002/06/01 20:41:47 Convert MLS to the new world order, largely based on the Biba work. Some XXX's still, and a panic in the statfs code on NFS boxes for some reason. Affected files ... ... //depot/projects/trustedbsd/mac/sys/security/mac_mls/mac_mls.c#32 edit Differences ... ==== //depot/projects/trustedbsd/mac/sys/security/mac_mls/mac_mls.c#32 (text+ko) ==== @@ -34,11 +34,12 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: $ + * $FreeBSD$ */ + /* * Developed by the TrustedBSD Project. - * Multi-Level Security Policy. + * MLS fixed label mandatory confidentiality policy. */ #include <sys/types.h> @@ -58,991 +59,1644 @@ #include <sys/socketvar.h> #include <sys/sysctl.h> +#include <fs/devfs/devfs.h> + #include <net/bpfdesc.h> #include <net/if.h> #include <net/if_types.h> #include <net/if_var.h> +#include <netinet/in.h> +#include <netinet/ip_var.h> + #include <security/mac_mls/mac_mls.h> SYSCTL_DECL(_security_mac); SYSCTL_NODE(_security_mac, OID_AUTO, mls, CTLFLAG_RW, 0, - "TrustedBSD Multi-Level Security sensitivity policy controls"); + "TrustedBSD mac_mls policy controls"); -static int mac_mls_enabled = 1; +static int mac_mls_enabled = 0; SYSCTL_INT(_security_mac_mls, OID_AUTO, enabled, CTLFLAG_RW, - &mac_mls_enabled, 0, "Enforce MLS sensitivity policy"); -TUNABLE_INT("security.mac.mls.enabled", &mac_mls_enabled); + &mac_mls_enabled, 0, "Enforce MAC/MLS policy"); + +static int destroyed_not_inited; +SYSCTL_INT(_security_mac_mls, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, + &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); + +static int slot; +#define SLOT(l) ((struct mac_mls *)LABEL_TO_SLOT((l), slot).l_ptr) + +MALLOC_DEFINE(M_MACMLS, "mls label", "MAC/MLS labels"); + +static struct mac_mls * +mls_alloc(int how) +{ + struct mac_mls *mac_mls; + + mac_mls = malloc(sizeof(struct mac_mls), M_MACMLS, M_ZERO | how); + + return (mac_mls); +} + +static void +mls_free(struct mac_mls *mac_mls) +{ + + if (mac_mls != NULL) + free(mac_mls, M_MACMLS); + else + atomic_add_int(&destroyed_not_inited, 1); +} static int -mac_mls_element_dominate(struct mac_mls_element *labela, - struct mac_mls_element *labelb) +mac_mls_dominate_element(struct mac_mls_element *a, + struct mac_mls_element *b) { - switch (labela->mme_type) { - case MAC_MLS_TYPE_LEVEL: - switch (labelb->mme_type) { + switch(a->mme_type) { + case MAC_MLS_TYPE_EQUAL: + case MAC_MLS_TYPE_HIGH: + return (1); + + case MAC_MLS_TYPE_LOW: + switch (b->mme_type) { case MAC_MLS_TYPE_LEVEL: - return (labela->mme_level >= labelb->mme_level); - case MAC_MLS_TYPE_LOW: - return (1); case MAC_MLS_TYPE_HIGH: return (0); + case MAC_MLS_TYPE_EQUAL: + case MAC_MLS_TYPE_LOW: return (1); + default: - panic("mac_mls_element_dominate(): Unknown " - "labelb mme_type (%d)\n", labelb->mme_type); + panic("mac_mls_dominate_element: b->mme_type invalid"); } - case MAC_MLS_TYPE_LOW: - switch (labelb->mme_type) { - case MAC_MLS_TYPE_LEVEL: - return (0); + + case MAC_MLS_TYPE_LEVEL: + switch (b->mme_type) { + case MAC_MLS_TYPE_EQUAL: case MAC_MLS_TYPE_LOW: return (1); + case MAC_MLS_TYPE_HIGH: return (0); - case MAC_MLS_TYPE_EQUAL: - return (1); + + case MAC_MLS_TYPE_LEVEL: + return (a->mme_level >= b->mme_level); + default: - panic("mac_mls_element_dominate(): Unknown " - "labelb mme_type (%d)\n", labelb->mme_type); + panic("mac_mls_dominate_element: b->mme_type invalid"); } - case MAC_MLS_TYPE_HIGH: - return (1); - case MAC_MLS_TYPE_EQUAL: - return (1); + default: - panic("mac_mls_element_dominate(): Unknown labela " - "mme_type (%d)\n", labela->mme_type); + panic("mac_mls_dominate_element: a->mme_type invalid"); } + + return (0); } static int -mac_mls_single_dominate(struct mac *labela, struct mac *labelb) +mac_mls_range_in_range(struct mac_mls *rangea, struct mac_mls *rangeb) { - KASSERT((labela->m_mls.mm_flags & MAC_MLS_FLAG_SINGLE) != 0, - ("mac_mls_single_dominate: labela does not have valid single")); - KASSERT((labelb->m_mls.mm_flags & MAC_MLS_FLAG_SINGLE) != 0, - ("mac_mls_single_dominate: labelb does not have valid single")); - - return (mac_mls_element_dominate(&labela->m_mls.mm_single, - &labelb->m_mls.mm_single)); + return (mac_mls_dominate_element(&rangea->mm_rangehigh, + &rangeb->mm_rangehigh) && + mac_mls_dominate_element(&rangeb->mm_rangelow, + &rangea->mm_rangelow)); } -/* - * Syntactic checks of label: 0 for success, else an errno. - */ static int -mac_mls_element_valid(struct mac_mls_element *element) +mac_mls_single_in_range(struct mac_mls *single, struct mac_mls *range) { - switch(element->mme_type) { - case MAC_MLS_TYPE_LEVEL: - break; - case MAC_MLS_TYPE_HIGH: - case MAC_MLS_TYPE_LOW: - case MAC_MLS_TYPE_EQUAL: - if (element->mme_level != 0) - return (EINVAL); - break; - default: - return (EINVAL); - } - return (0); + return (mac_mls_dominate_element(&range->mm_rangehigh, + &single->mm_single) && + mac_mls_dominate_element(&single->mm_single, + &range->mm_rangelow)); + + return (1); } static int -mac_mls_label_valid(struct mac *label) +mac_mls_dominate_single(struct mac_mls *a, struct mac_mls *b) { - int error; + KASSERT((a->mm_flags & MAC_MLS_FLAG_SINGLE) != 0, + ("mac_mls_dominate_single: a not single")); + KASSERT((b->mm_flags & MAC_MLS_FLAG_SINGLE) != 0, + ("mac_mls_dominate_single: b not single")); - if ((label->m_mls.mm_flags & ~MAC_MLS_FLAGS_BOTH) != 0) - return (EINVAL); - if (label->m_mls.mm_flags & MAC_MLS_FLAG_SINGLE) { - error = mac_mls_element_valid(&label->m_mls.mm_single); - if (error) - return (error); - } - if (label->m_mls.mm_flags & MAC_MLS_FLAG_RANGE) { - error = mac_mls_element_valid(&label->m_mls.mm_rangelow); - if (error) - return (error); - error = mac_mls_element_valid(&label->m_mls.mm_rangehigh); - if (error) - return (error); - if (!(mac_mls_element_dominate(&label->m_mls.mm_rangehigh, - &label->m_mls.mm_rangelow))) - return (EINVAL); - } - return (0); + return (mac_mls_dominate_element(&a->mm_single, &b->mm_single)); } static int -mac_mls_element_equal(struct mac_mls_element *labela, - struct mac_mls_element *labelb) +mac_mls_equal_element(struct mac_mls_element *a, struct mac_mls_element *b) { - return (mac_mls_element_dominate(labela, labelb) && - mac_mls_element_dominate(labelb, labela)); + if (a->mme_type == MAC_MLS_TYPE_EQUAL || + b->mme_type == MAC_MLS_TYPE_EQUAL) + return (1); + + return (a->mme_type == b->mme_type && a->mme_level == b->mme_level); } static int -mac_mls_single_equal(struct mac *labela, struct mac *labelb) +mac_mls_equal_range(struct mac_mls *a, struct mac_mls *b) { - KASSERT((labela->m_mls.mm_flags & MAC_MLS_FLAG_SINGLE) != 0, - ("mac_mls_single_equal: labela does not have valid single")); - KASSERT((labelb->m_mls.mm_flags & MAC_MLS_FLAG_SINGLE) != 0, - ("mac_mls_single_equal: labelb does not have valid single")); + KASSERT((a->mm_flags & MAC_MLS_FLAG_RANGE) != 0, + ("mac_mls_equal_range: a not range")); + KASSERT((b->mm_flags & MAC_MLS_FLAG_RANGE) != 0, + ("mac_mls_equal_range: b not range")); - return (mac_mls_element_equal(&labela->m_mls.mm_single, - &labelb->m_mls.mm_single)); + return (mac_mls_equal_element(&a->mm_rangelow, &b->mm_rangelow) && + mac_mls_equal_element(&a->mm_rangehigh, &b->mm_rangehigh)); } static int -mac_mls_equal(struct mac *labela, struct mac *labelb) +mac_mls_equal_single(struct mac_mls *a, struct mac_mls *b) { - int single_match, rangelow_match, rangehigh_match; + + KASSERT((a->mm_flags & MAC_MLS_FLAG_SINGLE) != 0, + ("mac_mls_equal_single: a not single")); + KASSERT((b->mm_flags & MAC_MLS_FLAG_SINGLE) != 0, + ("mac_mls_equal_single: b not single")); - single_match = mac_mls_element_equal(&labela->m_mls.mm_single, - &labelb->m_mls.mm_single); - rangelow_match = mac_mls_element_equal(&labela->m_mls.mm_rangelow, - &labelb->m_mls.mm_rangelow); - rangehigh_match = mac_mls_element_equal(&labela->m_mls.mm_rangehigh, - &labelb->m_mls.mm_rangehigh); - return (single_match && rangelow_match && rangehigh_match); + return (mac_mls_equal_element(&a->mm_single, &b->mm_single)); } static int -mac_mls_single_in_range(struct mac *labelsingle, struct mac *labelrange) +mac_mls_valid(struct mac_mls *mac_mls) { - int between = 1; + + if (mac_mls->mm_flags & MAC_MLS_FLAG_SINGLE) { + switch (mac_mls->mm_single.mme_type) { + case MAC_MLS_TYPE_LEVEL: + break; + + case MAC_MLS_TYPE_EQUAL: + case MAC_MLS_TYPE_HIGH: + case MAC_MLS_TYPE_LOW: + if (mac_mls->mm_single.mme_level != 0) + return (EINVAL); + break; + + default: + return (EINVAL); + } + } else { + if (mac_mls->mm_single.mme_type != MAC_MLS_TYPE_UNDEF) + return (EINVAL); + } + + if (mac_mls->mm_flags & MAC_MLS_FLAG_RANGE) { + switch (mac_mls->mm_rangelow.mme_type) { + case MAC_MLS_TYPE_LEVEL: + break; + + case MAC_MLS_TYPE_EQUAL: + case MAC_MLS_TYPE_HIGH: + case MAC_MLS_TYPE_LOW: + if (mac_mls->mm_rangelow.mme_level != 0) + return (EINVAL); + break; + + default: + return (EINVAL); + } + + switch (mac_mls->mm_rangehigh.mme_type) { + case MAC_MLS_TYPE_LEVEL: + break; + + case MAC_MLS_TYPE_EQUAL: + case MAC_MLS_TYPE_HIGH: + case MAC_MLS_TYPE_LOW: + if (mac_mls->mm_rangehigh.mme_level != 0) + return (EINVAL); + break; + + default: + return (EINVAL); + } + if (!mac_mls_dominate_element(&mac_mls->mm_rangehigh, + &mac_mls->mm_rangelow)) + return (EINVAL); + } else { + if (mac_mls->mm_rangelow.mme_type != MAC_MLS_TYPE_UNDEF || + mac_mls->mm_rangehigh.mme_type != MAC_MLS_TYPE_UNDEF) + return (EINVAL); + } - between &= mac_mls_element_dominate(&labelrange->m_mls.mm_rangehigh, - &labelsingle->m_mls.mm_single); - between &= mac_mls_element_dominate(&labelsingle->m_mls.mm_single, - &labelrange->m_mls.mm_rangelow); - return (between); + return (0); } static void -mac_mls_init_label(struct mac *label) +mac_mls_set_range(struct mac_mls *mac_mls, u_short typelow, + u_short levellow, u_short typehigh, u_short levelhigh) { - bzero(&label->m_mls, sizeof(label->m_mls)); + mac_mls->mm_rangelow.mme_type = typelow; + mac_mls->mm_rangelow.mme_level = levellow; + mac_mls->mm_rangehigh.mme_type = typehigh; + mac_mls->mm_rangehigh.mme_level = levelhigh; } static void -mac_mls_set_single(struct mac *label, u_short type, u_short level) +mac_mls_set_single(struct mac_mls *mac_mls, u_short type, u_short level) { - label->m_mls.mm_single.mme_type = type; - label->m_mls.mm_single.mme_level = level; - label->m_mls.mm_flags |= MAC_MLS_FLAG_SINGLE; + mac_mls->mm_single.mme_type = type; + mac_mls->mm_single.mme_level = level; + mac_mls->mm_flags |= MAC_MLS_FLAG_SINGLE; } static void -mac_mls_set_range(struct mac *label, u_short typelow, u_short levellow, - u_short typehigh, u_short levelhigh) +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")); - label->m_mls.mm_rangelow.mme_type = typelow; - label->m_mls.mm_rangelow.mme_level = levellow; - label->m_mls.mm_rangehigh.mme_type = typehigh; - label->m_mls.mm_rangehigh.mme_level = levelhigh; - label->m_mls.mm_flags |= MAC_MLS_FLAG_RANGE; + labelto->mm_rangelow = labelfrom->mm_rangelow; + labelto->mm_rangehigh = labelfrom->mm_rangehigh; + labelto->mm_flags |= MAC_MLS_FLAG_RANGE; } static void -mac_mls_copy_label(struct mac *labelfrom, struct mac *labelto) +mac_mls_copy_single(struct mac_mls *labelfrom, struct mac_mls *labelto) { - bcopy(&labelfrom->m_mls, &labelto->m_mls, sizeof(labelto->m_mls)); + KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_SINGLE) != 0, + ("mac_mls_copy_single: labelfrom not single")); + + labelto->mm_single = labelfrom->mm_single; + labelto->mm_flags |= MAC_MLS_FLAG_SINGLE; } static void -mac_mls_copy_single(struct mac *labelfrom, struct mac *labelto) +mac_mls_copy_single_to_range(struct mac_mls *labelfrom, + struct mac_mls *labelto) { - KASSERT((labelfrom->m_mls.mm_flags & MAC_MLS_FLAG_SINGLE) != 0, - ("mac_mls_copy_single: labelfrom not single")); + KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_SINGLE) != 0, + ("mac_mls_copy_single_to_range: labelfrom not single")); + + labelto->mm_rangelow = labelfrom->mm_single; + labelto->mm_rangehigh = labelfrom->mm_single; + labelto->mm_flags |= MAC_MLS_FLAG_RANGE; +} + +/* + * Policy module operations. + */ +static void +mac_mls_destroy(struct mac_policy_conf *conf) +{ - bcopy(&labelfrom->m_mls.mm_single, &labelto->m_mls.mm_single, - sizeof(labelto->m_mls.mm_single)); - labelto->m_mls.mm_flags |= MAC_MLS_FLAG_SINGLE; } -#if 0 static void -mac_mls_copy_range(struct mac *labelfrom, struct mac *labelto) +mac_mls_init(struct mac_policy_conf *conf) { - bcopy(&labelfrom->m_mls.mm_rangelow, &labelto->m_mls.mm_rangelow, - sizeof(labelto->m_mls.mm_rangelow)); - bcopy(&labelfrom->m_mls.mm_rangehigh, &labelto->m_mls.mm_rangehigh, - sizeof(labelto->m_mls.mm_rangehigh)); - labelto->m_mls.mm_flags |= MAC_MLS_FLAG_RANGE; } -#endif /* - * Initialize system processes as MAC_MLS_TYPE_EQUAL so that they can - * access any system resource with impunity. + * Label operations. */ static void -mac_mls_create_proc0(struct ucred *cred) +mac_mls_init_bpfdesc(struct bpf_d *bpf_d, struct label *label) +{ + + SLOT(label) = mls_alloc(M_WAITOK); +} + +static void +mac_mls_init_devfsdirent(struct devfs_dirent *devfs_dirent, + struct label *label) { - mac_mls_init_label(&cred->cr_label); - mac_mls_set_single(&cred->cr_label, MAC_MLS_TYPE_EQUAL, 0); - mac_mls_set_range(&cred->cr_label, MAC_MLS_TYPE_LOW, 0, - MAC_MLS_TYPE_HIGH, 0); + SLOT(label) = mls_alloc(M_WAITOK); } -/* - * Initialize user processes as MAC_MLS_TYPE_LOW to allow the user boot - * sequence to rely on low-sensitivity objects. - */ static void -mac_mls_create_proc1(struct ucred *cred) +mac_mls_init_ifnet(struct ifnet *ifnet, struct label *label) { - mac_mls_init_label(&cred->cr_label); - mac_mls_set_single(&cred->cr_label, MAC_MLS_TYPE_LOW, 0); - mac_mls_set_range(&cred->cr_label, MAC_MLS_TYPE_LOW, 0, - MAC_MLS_TYPE_HIGH, 0); + SLOT(label) = mls_alloc(M_WAITOK); } static void -mac_mls_create_subject(struct ucred *cred_parent, struct ucred *cred_child) +mac_mls_init_ipq(struct ipq *ipq, struct label *label) { - mac_mls_copy_label(&cred_parent->cr_label, &cred_child->cr_label); + SLOT(label) = mls_alloc(M_WAITOK); } static int -mac_mls_cred_check_relabel_subject(struct ucred *cred, struct mac *newlabel) +mac_mls_init_mbuf(struct mbuf *mbuf, int how, struct label *label) { - int error, privilege_needed; - error = mac_mls_label_valid(newlabel); - if (error) - return (error); - /* Require both range and single entries for subjects. */ - if ((newlabel->m_mls.mm_flags & MAC_MLS_FLAGS_BOTH) != - MAC_MLS_FLAGS_BOTH) - return (EINVAL); - /* - * Accept the change if: - * o Range is the same as current range. - * o Single is in the current range. - */ - privilege_needed = 0; - if (!mac_mls_element_equal(&cred->cr_label.m_mls.mm_rangehigh, - &newlabel->m_mls.mm_rangehigh)) - privilege_needed = 1; - if (!mac_mls_element_equal(&cred->cr_label.m_mls.mm_rangelow, - &newlabel->m_mls.mm_rangelow)) - privilege_needed = 1; - if (!mac_mls_single_in_range(newlabel, &cred->cr_label)) - privilege_needed = 1; - if (privilege_needed) { - error = suser_cred(cred, 0); - if (error) - return (error); - } + + SLOT(label) = mls_alloc(how); + if (SLOT(label) == NULL) + return (ENOMEM); + return (0); } -static int -mac_mls_cred_check_relabel_vnode(struct ucred *cred, struct vnode *vp, - struct mac *oldlabel, struct mac *newlabel) +static void +mac_mls_init_mount(struct mount *mount, struct label *mntlabel, + struct label *fslabel) +{ + + SLOT(mntlabel) = mls_alloc(M_WAITOK); + SLOT(fslabel) = mls_alloc(M_WAITOK); +} + +static void +mac_mls_init_socket(struct socket *socket, struct label *label, + struct label *peerlabel) +{ + + SLOT(label) = mls_alloc(M_WAITOK); + SLOT(peerlabel) = mls_alloc(M_WAITOK); +} + +static void +mac_mls_init_subject(struct ucred *ucred, struct label *label) +{ + + SLOT(label) = mls_alloc(M_WAITOK); +} + +static void +mac_mls_init_temp(struct label *label) +{ + + SLOT(label) = mls_alloc(M_WAITOK); +} + +static void +mac_mls_init_vnode(struct vnode *vp, struct label *label) +{ + + SLOT(label) = mls_alloc(M_WAITOK); +} + +static void +mac_mls_destroy_bpfdesc(struct bpf_d *bpf_d, struct label *label) +{ + + mls_free(SLOT(label)); + SLOT(label) = NULL; +} + +static void +mac_mls_destroy_devfsdirent(struct devfs_dirent *devfs_dirent, + struct label *label) +{ + + mls_free(SLOT(label)); + SLOT(label) = NULL; +} + +static void +mac_mls_destroy_ifnet(struct ifnet *ifnet, struct label *label) +{ + + mls_free(SLOT(label)); + SLOT(label) = NULL; +} + +static void +mac_mls_destroy_ipq(struct ipq *ipq, struct label *label) +{ + + mls_free(SLOT(label)); + SLOT(label) = NULL; +} + +static void +mac_mls_destroy_mbuf(struct mbuf *mbuf, struct label *label) { - int error, privilege_needed; - error = mac_mls_label_valid(newlabel); - if (error) - return (error); - /* Only single labels for vnodes. */ - if ((newlabel->m_mls.mm_flags & MAC_MLS_FLAGS_BOTH) != - MAC_MLS_FLAG_SINGLE) - return (EINVAL); - /* - * Accept the change if: - * o Old label is in the current subject range. - * o New label is in the current subject range. - */ - privilege_needed = 0; - if (!(mac_mls_single_in_range(oldlabel, &cred->cr_label))) - privilege_needed = 1; - if (!(mac_mls_single_in_range(newlabel, &cred->cr_label))) - privilege_needed = 1; - if (privilege_needed) { - error = suser_cred(cred, 0); - if (error) - return (error); - } - return (0); + mls_free(SLOT(label)); + SLOT(label) = NULL; } static void -mac_mls_relabel_subject(struct ucred *cred, struct mac *newlabel) +mac_mls_destroy_mount(struct mount *mount, struct label *mntlabel, + struct label *fslabel) { - mac_mls_copy_label(newlabel, &cred->cr_label); + mls_free(SLOT(mntlabel)); + SLOT(mntlabel) = NULL; + mls_free(SLOT(fslabel)); + SLOT(fslabel) = NULL; } -static int -mac_mls_ifnet_check_send_mbuf(struct ifnet *ifnet, struct mbuf *m) +static void +mac_mls_destroy_socket(struct socket *socket, struct label *label, + struct label *peerlabel) { - if (!mac_mls_enabled) - return (0); - if (mac_mls_single_in_range(&m->m_pkthdr.label, &ifnet->if_label)) - return (0); - else - return (EPERM); + mls_free(SLOT(label)); + SLOT(label) = NULL; + mls_free(SLOT(peerlabel)); + SLOT(peerlabel) = NULL; } -static int -mac_mls_bpfdesc_check_receive_from_ifnet(struct bpf_d *bpf_d, - struct ifnet *ifnet) +static void +mac_mls_destroy_subject(struct ucred *ucred, struct label *label) { - if (!mac_mls_enabled) - return (0); - if (mac_mls_single_equal(&bpf_d->bd_label, &ifnet->if_label)) - return (0); - else - return (EPERM); + mls_free(SLOT(label)); + SLOT(label) = NULL; } -static int -mac_mls_socket_check_receive_mbuf(struct socket *so, struct mbuf *m) +static void +mac_mls_destroy_temp(struct label *label) { - if (!mac_mls_enabled) - return (0); - if (mac_mls_single_equal(&so->so_label, &m->m_pkthdr.label)) - return (0); - else - return (EPERM); + mls_free(SLOT(label)); + SLOT(label) = NULL; } static void -mac_mls_create_ifnet(struct ifnet *ifnet) +mac_mls_destroy_vnode(struct vnode *vp, struct label *label) +{ + + mls_free(SLOT(label)); + SLOT(label) = NULL; +} + +static int +mac_mls_externalize(struct label *label, struct mac *extmac) { - int interface_label_type; + struct mac_mls *mac_mls; + + mac_mls = SLOT(label); + + if (mac_mls == NULL) { + printf("mac_mls_externalize: NULL pointer\n"); + return (0); + } + + extmac->m_mls = *mac_mls; - if (ifnet->if_type == IFT_LOOP) - interface_label_type = MAC_MLS_TYPE_EQUAL; - else - interface_label_type = MAC_MLS_TYPE_LOW; - mac_mls_init_label(&ifnet->if_label); - mac_mls_set_single(&ifnet->if_label, interface_label_type, 0); - mac_mls_set_range(&ifnet->if_label, interface_label_type, 0, - interface_label_type, 0); + return (0); } static int -mac_mls_cred_check_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, - struct mac *newlabel) +mac_mls_internalize(struct label *label, struct mac *extmac) { + struct mac_mls *mac_mls; int error; - error = mac_mls_label_valid(newlabel); + mac_mls = SLOT(label); + + error = mac_mls_valid(mac_mls); if (error) return (error); - /* Require both single and range for interfaces. */ - if ((newlabel->m_mls.mm_flags & MAC_MLS_FLAGS_BOTH) != - MAC_MLS_FLAGS_BOTH) - return (EINVAL); - return (suser_cred(cred, 0)); + + *mac_mls = extmac->m_mls; + + return (0); } +/* + * Labeling event operations: file system objects, and things that look + * a lot like file system objects. + */ static void -mac_mls_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, - struct mac *newlabel) +mac_mls_create_devfs_device(dev_t dev, struct devfs_dirent *devfs_dirent, + struct label *label) { + struct mac_mls *mac_mls; + int mls_type; - mac_mls_copy_label(newlabel, &ifnet->if_label); + mac_mls = SLOT(label); + if (strcmp(dev->si_name, "null") == 0 || + strcmp(dev->si_name, "zero") == 0 || + strcmp(dev->si_name, "random") == 0 || + strncmp(dev->si_name, "fd/", strlen("fd/")) == 0) + mls_type = MAC_MLS_TYPE_EQUAL; + else if (strcmp(dev->si_name, "kmem") == 0 || + strcmp(dev->si_name, "mem") == 0) + mls_type = MAC_MLS_TYPE_HIGH; + else + mls_type = MAC_MLS_TYPE_LOW; + mac_mls_set_single(mac_mls, mls_type, 0); } static void -mac_mls_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d) +mac_mls_create_devfs_directory(char *dirname, int dirnamelen, + struct devfs_dirent *devfs_dirent, struct label *label) { + struct mac_mls *mac_mls; - mac_mls_init_label(&bpf_d->bd_label); - mac_mls_copy_single(&cred->cr_label, &bpf_d->bd_label); + mac_mls = SLOT(label); + mac_mls_set_single(mac_mls, MAC_MLS_TYPE_HIGH, 0); } static void -mac_mls_create_mbuf_datagram_from_mbuf_fragmentqueue( - struct mbuf *fragmentqueue, struct mbuf *datagram) +mac_mls_create_devfs_vnode(struct devfs_dirent *devfs_dirent, + struct label *direntlabel, struct vnode *vp, struct label *vnodelabel) { + struct mac_mls *source, *dest; - mac_mls_init_label(&datagram->m_pkthdr.label); - mac_mls_copy_single(&fragmentqueue->m_pkthdr.label, - &datagram->m_pkthdr.label); + source = SLOT(direntlabel); + dest = SLOT(vnodelabel); + mac_mls_copy_single(source, dest); } static void -mac_mls_create_mbuf_fragment_from_mbuf(struct mbuf *mbuf, - struct mbuf *fragment) +mac_mls_create_vnode_from_vnode(struct ucred *cred, struct vnode *parent, + struct label *parentlabel, struct vnode *child, + struct label *childlabel) { + struct mac_mls *source, *dest; - mac_mls_init_label(&fragment->m_pkthdr.label); - mac_mls_copy_single(&mbuf->m_pkthdr.label, &fragment->m_pkthdr.label); + source = SLOT(&cred->cr_label); + dest = SLOT(childlabel); + + mac_mls_copy_single(source, dest); } static void -mac_mls_create_mbuf_fragmentqueue_from_mbuf_fragment(struct mbuf *fragment, - struct mbuf *fragmentqueue) +mac_mls_create_mount(struct ucred *cred, struct mount *mp, + struct label *mntlabel, struct label *fslabel) { + struct mac_mls *source, *dest; - mac_mls_init_label(&fragmentqueue->m_pkthdr.label); - mac_mls_copy_single(&fragment->m_pkthdr.label, - &fragmentqueue->m_pkthdr.label); + source = SLOT(&cred->cr_label); + dest = SLOT(mntlabel); + mac_mls_copy_single(source, dest); + dest = SLOT(fslabel); + mac_mls_copy_single(source, dest); } static void -mac_mls_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf) +mac_mls_create_root_mount(struct ucred *cred, struct mount *mp, + struct label *mntlabel, struct label *fslabel) { + struct mac_mls *mac_mls; - mac_mls_init_label(&newmbuf->m_pkthdr.label); - mac_mls_copy_single(&oldmbuf->m_pkthdr.label, - &newmbuf->m_pkthdr.label); + /* Always mount root as high integrity. */ + mac_mls = SLOT(fslabel); + mac_mls_set_single(mac_mls, MAC_MLS_TYPE_LOW, 0); + mac_mls = SLOT(mntlabel); + mac_mls_set_single(mac_mls, MAC_MLS_TYPE_LOW, 0); } static void -mac_mls_create_mbuf_linklayer_for_ifnet(struct ifnet *ifnet, - struct mbuf *mbuf) +mac_mls_relabel_vnode(struct ucred *cred, struct vnode *vp, + struct label *vnodelabel, struct label *label) { + struct mac_mls *source, *dest; - mac_mls_init_label(&mbuf->m_pkthdr.label); - mac_mls_set_single(&mbuf->m_pkthdr.label, MAC_MLS_TYPE_EQUAL, 0); + source = SLOT(label); + dest = SLOT(vnodelabel); + + mac_mls_copy_single(source, dest); } static void -mac_mls_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *m) +mac_mls_update_devfsdirent_from_vnode(struct devfs_dirent *devfs_dirent, + struct label *direntlabel, struct vnode *vp, struct label *vnodelabel) { + struct mac_mls *source, *dest; - mac_mls_init_label(&m->m_pkthdr.label); - mac_mls_copy_single(&ifnet->if_label, &m->m_pkthdr.label); + source = SLOT(vnodelabel); + dest = SLOT(direntlabel); + + mac_mls_copy_single(source, dest); } static void -mac_mls_create_mbuf_multicast_encap_from_mbuf(struct mbuf *oldmbuf, - struct ifnet *ifnet, struct mbuf *newmbuf) +mac_mls_update_procfsvnode_from_subject(struct vnode *vp, + struct label *vnodelabel, struct ucred *cred) { + struct mac_mls *source, *dest; - mac_mls_init_label(&newmbuf->m_pkthdr.label); - mac_mls_copy_single(&oldmbuf->m_pkthdr.label, - &newmbuf->m_pkthdr.label); + source = SLOT(&cred->cr_label); + dest = SLOT(vnodelabel); + + /* + * Only copy the single, not the range, since vnodes only have + * a single. + */ + mac_mls_copy_single(source, dest); } static void -mac_mls_create_mbuf_netlayer_from_mbuf(struct mbuf *oldmbuf, - struct mbuf *newmbuf) +mac_mls_update_vnode_from_externalized(struct vnode *vp, + struct label *vnodelabel, struct mac *extmac) { + struct mac_mls *source, *dest; - mac_mls_init_label(&newmbuf->m_pkthdr.label); - mac_mls_copy_single(&oldmbuf->m_pkthdr.label, - &newmbuf->m_pkthdr.label); + /* XXX: Validity check. */ + source = &extmac->m_mls; + dest = SLOT(vnodelabel); + + mac_mls_copy_single(source, dest); } -static int -mac_mls_mbuf_fragment_matches_mbuf_fragmentqueue(struct mbuf *fragment, - struct mbuf *fragmentqueue) +static void +mac_mls_update_vnode_from_mount(struct vnode *vp, struct label *vnodelabel, + struct mount *mp, struct label *fslabel) { + struct mac_mls *source, *dest; + + source = SLOT(fslabel); + dest = SLOT(vnodelabel); - return (mac_mls_single_equal(&fragment->m_pkthdr.label, - &fragmentqueue->m_pkthdr.label)); + mac_mls_copy_single(source, dest); } +/* + * Labeling event operations: IPC object. + */ static void -mac_mls_create_mbuf_from_socket(struct socket *so, struct mbuf *m) +mac_mls_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, + struct mbuf *m, struct label *mbuflabel) { + struct mac_mls *source, *dest; + + source = SLOT(socketlabel); + dest = SLOT(mbuflabel); - mac_mls_init_label(&m->m_pkthdr.label); - mac_mls_copy_single(&so->so_label, &m->m_pkthdr.label); + mac_mls_copy_single(source, dest); } >>> TRUNCATED FOR MAIL (1000 lines) <<< 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?200206020342.g523glD82295>