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
This commit is contained in:
parent
8d4da7c310
commit
5b5e6eeb1b
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user