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:
rwatson 2004-06-24 03:34:46 +00:00
parent 8d4da7c310
commit 5b5e6eeb1b
8 changed files with 55 additions and 0 deletions

View File

@ -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);

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,