From 2220907b6ece3ccf47b7696ff8b5d2d4b35be066 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Thu, 24 Jun 2004 03:34:46 +0000 Subject: [PATCH] Introduce a temporary mutex, mac_ifnet_mtx, to lock MAC labels on network interfaces. This global mutex will protect all ifnet labels. Acquire the mutex across various MAC activities on interfaces, such as security checks, propagating interface labels to mbufs generated from the interface, retrieving and setting the interface label. Introduce mpo_copy_ifnet_label MAC policy entry point to copy the value of an interface label from one label to another. Use this to avoid performing a label externalize while holding mac_ifnet_mtx; copy the label to a temporary ifnet label and then externalize that. Implement mpo_copy_ifnet_label for various MAC policies that implement interface labeling using generic label copying routines. Obtained from: TrustedBSD Project Sponsored by: DARPA, McAfee Research --- sys/security/mac/mac_net.c | 38 ++++++++++++++++++++++++++++++ sys/security/mac/mac_policy.h | 2 ++ sys/security/mac_biba/mac_biba.c | 1 + sys/security/mac_lomac/mac_lomac.c | 1 + sys/security/mac_mls/mac_mls.c | 1 + sys/security/mac_stub/mac_stub.c | 1 + sys/security/mac_test/mac_test.c | 9 +++++++ sys/sys/mac_policy.h | 2 ++ 8 files changed, 55 insertions(+) diff --git a/sys/security/mac/mac_net.c b/sys/security/mac/mac_net.c index 51e6251a15c..d0afba93743 100644 --- a/sys/security/mac/mac_net.c +++ b/sys/security/mac/mac_net.c @@ -83,6 +83,16 @@ SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mbufs, CTLFLAG_RD, &nmacmbufs, 0, "number of mbufs in use"); #endif +/* + * XXXRW: struct ifnet locking is incomplete in the network code, so we + * use our own global mutex for struct ifnet. Non-ideal, but should help + * in the SMP environment. + */ +static struct mtx mac_ifnet_mtx; +MTX_SYSINIT(mac_ifnet_mtx, &mac_ifnet_mtx, "mac_ifnet", MTX_DEF); +#define MAC_IFNET_LOCK(ifp) mtx_lock(&mac_ifnet_mtx) +#define MAC_IFNET_UNLOCK(ifp) mtx_unlock(&mac_ifnet_mtx) + struct label * mac_mbuf_to_label(struct mbuf *mbuf) { @@ -243,6 +253,13 @@ mac_copy_mbuf_tag(struct m_tag *src, struct m_tag *dest) MAC_PERFORM(copy_mbuf_label, src_label, dest_label); } +static void +mac_copy_ifnet_label(struct label *src, struct label *dest) +{ + + MAC_PERFORM(copy_ifnet_label, src, dest); +} + static int mac_externalize_ifnet_label(struct label *label, char *elements, char *outbuf, size_t outbuflen) @@ -268,7 +285,9 @@ void mac_create_ifnet(struct ifnet *ifnet) { + MAC_IFNET_LOCK(ifnet); MAC_PERFORM(create_ifnet, ifnet, ifnet->if_label); + MAC_IFNET_UNLOCK(ifnet); } void @@ -310,8 +329,10 @@ mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf) label = mac_mbuf_to_label(mbuf); + MAC_IFNET_LOCK(ifnet); MAC_PERFORM(create_mbuf_linklayer, ifnet, ifnet->if_label, mbuf, label); + MAC_IFNET_UNLOCK(ifnet); } void @@ -321,8 +342,10 @@ mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf) label = mac_mbuf_to_label(mbuf); + MAC_IFNET_LOCK(ifnet); MAC_PERFORM(create_mbuf_from_ifnet, ifnet, ifnet->if_label, mbuf, label); + MAC_IFNET_UNLOCK(ifnet); } void @@ -334,8 +357,10 @@ mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet, oldmbuflabel = mac_mbuf_to_label(oldmbuf); newmbuflabel = mac_mbuf_to_label(newmbuf); + MAC_IFNET_LOCK(ifnet); MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, oldmbuflabel, ifnet, ifnet->if_label, newmbuf, newmbuflabel); + MAC_IFNET_UNLOCK(ifnet); } void @@ -360,8 +385,10 @@ mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet) if (!mac_enforce_network) return (0); + MAC_IFNET_LOCK(ifnet); MAC_CHECK(check_bpfdesc_receive, bpf_d, bpf_d->bd_label, ifnet, ifnet->if_label); + MAC_IFNET_UNLOCK(ifnet); return (error); } @@ -379,8 +406,10 @@ mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf) label = mac_mbuf_to_label(mbuf); + MAC_IFNET_LOCK(ifnet); MAC_CHECK(check_ifnet_transmit, ifnet, ifnet->if_label, mbuf, label); + MAC_IFNET_UNLOCK(ifnet); return (error); } @@ -390,6 +419,7 @@ mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, struct ifnet *ifnet) { char *elements, *buffer; + struct label *intlabel; struct mac mac; int error; @@ -409,8 +439,13 @@ mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, } buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); + intlabel = mac_ifnet_label_alloc(); + MAC_IFNET_LOCK(ifnet); + mac_copy_ifnet_label(ifnet->if_label, intlabel); + MAC_IFNET_UNLOCK(ifnet); error = mac_externalize_ifnet_label(ifnet->if_label, elements, buffer, mac.m_buflen); + mac_ifnet_label_free(intlabel); if (error == 0) error = copyout(buffer, mac.m_string, strlen(buffer)+1); @@ -463,14 +498,17 @@ mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, return (error); } + MAC_IFNET_LOCK(ifnet); MAC_CHECK(check_ifnet_relabel, cred, ifnet, ifnet->if_label, intlabel); if (error) { + MAC_IFNET_UNLOCK(ifnet); mac_ifnet_label_free(intlabel); return (error); } MAC_PERFORM(relabel_ifnet, cred, ifnet, ifnet->if_label, intlabel); + MAC_IFNET_UNLOCK(ifnet); mac_ifnet_label_free(intlabel); return (0); diff --git a/sys/security/mac/mac_policy.h b/sys/security/mac/mac_policy.h index 1748a40d8ed..53ad2817840 100644 --- a/sys/security/mac/mac_policy.h +++ b/sys/security/mac/mac_policy.h @@ -122,6 +122,8 @@ struct mac_policy_ops { void (*mpo_destroy_vnode_label)(struct label *label); void (*mpo_copy_cred_label)(struct label *src, struct label *dest); + void (*mpo_copy_ifnet_label)(struct label *src, + struct label *dest); void (*mpo_copy_mbuf_label)(struct label *src, struct label *dest); void (*mpo_copy_pipe_label)(struct label *src, diff --git a/sys/security/mac_biba/mac_biba.c b/sys/security/mac_biba/mac_biba.c index 005c967775a..34c30fa9535 100644 --- a/sys/security/mac_biba/mac_biba.c +++ b/sys/security/mac_biba/mac_biba.c @@ -2663,6 +2663,7 @@ static struct mac_policy_ops mac_biba_ops = .mpo_destroy_socket_peer_label = mac_biba_destroy_label, .mpo_destroy_vnode_label = mac_biba_destroy_label, .mpo_copy_cred_label = mac_biba_copy_label, + .mpo_copy_ifnet_label = mac_biba_copy_label, .mpo_copy_mbuf_label = mac_biba_copy_label, .mpo_copy_pipe_label = mac_biba_copy_label, .mpo_copy_socket_label = mac_biba_copy_label, diff --git a/sys/security/mac_lomac/mac_lomac.c b/sys/security/mac_lomac/mac_lomac.c index 9d4ef7b8a03..5e5d56911fe 100644 --- a/sys/security/mac_lomac/mac_lomac.c +++ b/sys/security/mac_lomac/mac_lomac.c @@ -2643,6 +2643,7 @@ static struct mac_policy_ops mac_lomac_ops = .mpo_destroy_socket_peer_label = mac_lomac_destroy_label, .mpo_destroy_vnode_label = mac_lomac_destroy_label, .mpo_copy_cred_label = mac_lomac_copy_label, + .mpo_copy_ifnet_label = mac_lomac_copy_label, .mpo_copy_mbuf_label = mac_lomac_copy_label, .mpo_copy_pipe_label = mac_lomac_copy_label, .mpo_copy_socket_label = mac_lomac_copy_label, diff --git a/sys/security/mac_mls/mac_mls.c b/sys/security/mac_mls/mac_mls.c index e683790e998..4fcf0140634 100644 --- a/sys/security/mac_mls/mac_mls.c +++ b/sys/security/mac_mls/mac_mls.c @@ -2441,6 +2441,7 @@ static struct mac_policy_ops mac_mls_ops = .mpo_destroy_socket_peer_label = mac_mls_destroy_label, .mpo_destroy_vnode_label = mac_mls_destroy_label, .mpo_copy_cred_label = mac_mls_copy_label, + .mpo_copy_ifnet_label = mac_mls_copy_label, .mpo_copy_mbuf_label = mac_mls_copy_label, .mpo_copy_pipe_label = mac_mls_copy_label, .mpo_copy_socket_label = mac_mls_copy_label, diff --git a/sys/security/mac_stub/mac_stub.c b/sys/security/mac_stub/mac_stub.c index f6874880d4f..01cb99fb67f 100644 --- a/sys/security/mac_stub/mac_stub.c +++ b/sys/security/mac_stub/mac_stub.c @@ -1057,6 +1057,7 @@ static struct mac_policy_ops mac_stub_ops = .mpo_destroy_socket_peer_label = stub_destroy_label, .mpo_destroy_vnode_label = stub_destroy_label, .mpo_copy_cred_label = stub_copy_label, + .mpo_copy_ifnet_label = stub_copy_label, .mpo_copy_mbuf_label = stub_copy_label, .mpo_copy_pipe_label = stub_copy_label, .mpo_copy_socket_label = stub_copy_label, diff --git a/sys/security/mac_test/mac_test.c b/sys/security/mac_test/mac_test.c index 21be1553306..d476638fc5d 100644 --- a/sys/security/mac_test/mac_test.c +++ b/sys/security/mac_test/mac_test.c @@ -599,6 +599,14 @@ mac_test_copy_cred_label(struct label *src, struct label *dest) ASSERT_CRED_LABEL(dest); } +static void +mac_test_copy_ifnet_label(struct label *src, struct label *dest) +{ + + ASSERT_IFNET_LABEL(src); + ASSERT_IFNET_LABEL(dest); +} + static void mac_test_copy_mbuf_label(struct label *src, struct label *dest) { @@ -1892,6 +1900,7 @@ static struct mac_policy_ops mac_test_ops = .mpo_destroy_socket_peer_label = mac_test_destroy_socket_peer_label, .mpo_destroy_vnode_label = mac_test_destroy_vnode_label, .mpo_copy_cred_label = mac_test_copy_cred_label, + .mpo_copy_ifnet_label = mac_test_copy_ifnet_label, .mpo_copy_mbuf_label = mac_test_copy_mbuf_label, .mpo_copy_pipe_label = mac_test_copy_pipe_label, .mpo_copy_socket_label = mac_test_copy_socket_label, diff --git a/sys/sys/mac_policy.h b/sys/sys/mac_policy.h index 1748a40d8ed..53ad2817840 100644 --- a/sys/sys/mac_policy.h +++ b/sys/sys/mac_policy.h @@ -122,6 +122,8 @@ struct mac_policy_ops { void (*mpo_destroy_vnode_label)(struct label *label); void (*mpo_copy_cred_label)(struct label *src, struct label *dest); + void (*mpo_copy_ifnet_label)(struct label *src, + struct label *dest); void (*mpo_copy_mbuf_label)(struct label *src, struct label *dest); void (*mpo_copy_pipe_label)(struct label *src,