Continue work to optimize performance of "options MAC" when no MAC policy

modules are loaded by avoiding mbuf label lookups when policies aren't
loaded, pushing further socket locking into MAC policy modules, and
avoiding locking MAC ifnet locks when no policies are loaded:

- Check mac_policies_count before looking for mbuf MAC label m_tags in MAC
  Framework entry points.  We will still pay label lookup costs if MAC
  policies are present but don't require labels (typically a single mbuf
  header field read, but perhaps further indirection if IPSEC or other
  m_tag consumers are in use).

- Further push socket locking for socket-related access control checks and
  events into MAC policies from the MAC Framework, so that sockets are
  only locked if a policy specifically requires a lock to protect a label.
  This resolves lock order issues during sonewconn() and also in local
  domain socket cross-connect where multiple socket locks could not be
  held at once for the purposes of propagatig MAC labels across multiple
  sockets.  Eliminate mac_policy_count check in some entry points where it
  no longer avoids locking.

- Add mac_policy_count checking in some entry points relating to network
  interfaces that otherwise lock a global MAC ifnet lock used to protect
  ifnet labels.

Obtained from:	TrustedBSD Project
This commit is contained in:
Robert Watson 2009-06-03 18:46:28 +00:00
parent 097695e97a
commit 3de4046939
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=193391
11 changed files with 328 additions and 96 deletions

View File

@ -212,9 +212,7 @@ in_pcballoc(struct socket *so, struct inpcbinfo *pcbinfo)
error = mac_inpcb_init(inp, M_NOWAIT);
if (error != 0)
goto out;
SOCK_LOCK(so);
mac_inpcb_create(so, inp);
SOCK_UNLOCK(so);
#endif
#ifdef IPSEC
error = ipsec_init_policy(so, &inp->inp_sp);

View File

@ -61,6 +61,9 @@ mac_netatalk_aarp_send(struct ifnet *ifp, struct mbuf *m)
{
struct label *mlabel;
if (mac_policy_count == 0)
return;
mlabel = mac_mbuf_to_label(m);
MAC_IFNET_LOCK(ifp);

View File

@ -193,6 +193,9 @@ mac_ipq_reassemble(struct ipq *q, struct mbuf *m)
{
struct label *label;
if (mac_policy_count == 0)
return;
label = mac_mbuf_to_label(m);
MAC_POLICY_PERFORM_NOSLEEP(ipq_reassemble, q, q->ipq_label, m,
@ -204,6 +207,9 @@ mac_netinet_fragment(struct mbuf *m, struct mbuf *frag)
{
struct label *mlabel, *fraglabel;
if (mac_policy_count == 0)
return;
mlabel = mac_mbuf_to_label(m);
fraglabel = mac_mbuf_to_label(frag);
@ -216,6 +222,9 @@ mac_ipq_create(struct mbuf *m, struct ipq *q)
{
struct label *label;
if (mac_policy_count == 0)
return;
label = mac_mbuf_to_label(m);
MAC_POLICY_PERFORM_NOSLEEP(ipq_create, m, label, q, q->ipq_label);
@ -227,6 +236,10 @@ mac_inpcb_create_mbuf(struct inpcb *inp, struct mbuf *m)
struct label *mlabel;
INP_LOCK_ASSERT(inp);
if (mac_policy_count == 0)
return;
mlabel = mac_mbuf_to_label(m);
MAC_POLICY_PERFORM_NOSLEEP(inpcb_create_mbuf, inp, inp->inp_label, m,
@ -239,6 +252,9 @@ mac_ipq_match(struct mbuf *m, struct ipq *q)
struct label *label;
int result;
if (mac_policy_count == 0)
return (1);
label = mac_mbuf_to_label(m);
result = 1;
@ -252,6 +268,9 @@ mac_netinet_arp_send(struct ifnet *ifp, struct mbuf *m)
{
struct label *mlabel;
if (mac_policy_count == 0)
return;
mlabel = mac_mbuf_to_label(m);
MAC_IFNET_LOCK(ifp);
@ -265,6 +284,9 @@ mac_netinet_icmp_reply(struct mbuf *mrecv, struct mbuf *msend)
{
struct label *mrecvlabel, *msendlabel;
if (mac_policy_count == 0)
return;
mrecvlabel = mac_mbuf_to_label(mrecv);
msendlabel = mac_mbuf_to_label(msend);
@ -277,6 +299,9 @@ mac_netinet_icmp_replyinplace(struct mbuf *m)
{
struct label *label;
if (mac_policy_count == 0)
return;
label = mac_mbuf_to_label(m);
MAC_POLICY_PERFORM_NOSLEEP(netinet_icmp_replyinplace, m, label);
@ -287,6 +312,9 @@ mac_netinet_igmp_send(struct ifnet *ifp, struct mbuf *m)
{
struct label *mlabel;
if (mac_policy_count == 0)
return;
mlabel = mac_mbuf_to_label(m);
MAC_IFNET_LOCK(ifp);
@ -300,6 +328,9 @@ mac_netinet_tcp_reply(struct mbuf *m)
{
struct label *label;
if (mac_policy_count == 0)
return;
label = mac_mbuf_to_label(m);
MAC_POLICY_PERFORM_NOSLEEP(netinet_tcp_reply, m, label);
@ -310,6 +341,9 @@ mac_ipq_update(struct mbuf *m, struct ipq *q)
{
struct label *label;
if (mac_policy_count == 0)
return;
label = mac_mbuf_to_label(m);
MAC_POLICY_PERFORM_NOSLEEP(ipq_update, m, label, q, q->ipq_label);
@ -326,6 +360,9 @@ mac_inpcb_check_deliver(struct inpcb *inp, struct mbuf *m)
M_ASSERTPKTHDR(m);
if (mac_policy_count == 0)
return (0);
label = mac_mbuf_to_label(m);
MAC_POLICY_CHECK_NOSLEEP(inpcb_check_deliver, inp, inp->inp_label, m,
@ -371,6 +408,9 @@ mac_netinet_firewall_reply(struct mbuf *mrecv, struct mbuf *msend)
M_ASSERTPKTHDR(mrecv);
M_ASSERTPKTHDR(msend);
if (mac_policy_count == 0)
return;
mrecvlabel = mac_mbuf_to_label(mrecv);
msendlabel = mac_mbuf_to_label(msend);
@ -385,6 +425,9 @@ mac_netinet_firewall_send(struct mbuf *m)
M_ASSERTPKTHDR(m);
if (mac_policy_count == 0)
return;
label = mac_mbuf_to_label(m);
MAC_POLICY_PERFORM_NOSLEEP(netinet_firewall_send, m, label);
@ -455,6 +498,9 @@ mac_syncache_create_mbuf(struct label *sc_label, struct mbuf *m)
M_ASSERTPKTHDR(m);
if (mac_policy_count == 0)
return;
mlabel = mac_mbuf_to_label(m);
MAC_POLICY_PERFORM_NOSLEEP(syncache_create_mbuf, sc_label, m,

View File

@ -118,6 +118,9 @@ mac_ip6q_reassemble(struct ip6q *q6, struct mbuf *m)
{
struct label *label;
if (mac_policy_count == 0)
return;
label = mac_mbuf_to_label(m);
MAC_POLICY_PERFORM_NOSLEEP(ip6q_reassemble, q6, q6->ip6q_label, m,
@ -129,6 +132,9 @@ mac_ip6q_create(struct mbuf *m, struct ip6q *q6)
{
struct label *label;
if (mac_policy_count == 0)
return;
label = mac_mbuf_to_label(m);
MAC_POLICY_PERFORM_NOSLEEP(ip6q_create, m, label, q6,
@ -141,6 +147,9 @@ mac_ip6q_match(struct mbuf *m, struct ip6q *q6)
struct label *label;
int result;
if (mac_policy_count == 0)
return (1);
label = mac_mbuf_to_label(m);
result = 1;
@ -155,6 +164,9 @@ mac_ip6q_update(struct mbuf *m, struct ip6q *q6)
{
struct label *label;
if (mac_policy_count == 0)
return;
label = mac_mbuf_to_label(m);
MAC_POLICY_PERFORM_NOSLEEP(ip6q_update, m, label, q6,
@ -166,6 +178,9 @@ mac_netinet6_nd6_send(struct ifnet *ifp, struct mbuf *m)
{
struct label *mlabel;
if (mac_policy_count == 0)
return;
mlabel = mac_mbuf_to_label(m);
MAC_POLICY_PERFORM_NOSLEEP(netinet6_nd6_send, ifp, ifp->if_label, m,

View File

@ -296,6 +296,9 @@ void
mac_ifnet_create(struct ifnet *ifp)
{
if (mac_policy_count == 0)
return;
MAC_IFNET_LOCK(ifp);
MAC_POLICY_PERFORM_NOSLEEP(ifnet_create, ifp, ifp->if_label);
MAC_IFNET_UNLOCK(ifp);
@ -315,6 +318,9 @@ mac_bpfdesc_create_mbuf(struct bpf_d *d, struct mbuf *m)
BPFD_LOCK_ASSERT(d);
if (mac_policy_count == 0)
return;
label = mac_mbuf_to_label(m);
MAC_POLICY_PERFORM_NOSLEEP(bpfdesc_create_mbuf, d, d->bd_label, m,
@ -326,6 +332,9 @@ mac_ifnet_create_mbuf(struct ifnet *ifp, struct mbuf *m)
{
struct label *label;
if (mac_policy_count == 0)
return;
label = mac_mbuf_to_label(m);
MAC_IFNET_LOCK(ifp);
@ -344,6 +353,9 @@ mac_bpfdesc_check_receive(struct bpf_d *d, struct ifnet *ifp)
BPFD_LOCK_ASSERT(d);
if (mac_policy_count == 0)
return (0);
MAC_IFNET_LOCK(ifp);
MAC_POLICY_CHECK_NOSLEEP(bpfdesc_check_receive, d, d->bd_label, ifp,
ifp->if_label);
@ -364,6 +376,9 @@ mac_ifnet_check_transmit(struct ifnet *ifp, struct mbuf *m)
M_ASSERTPKTHDR(m);
if (mac_policy_count == 0)
return (0);
label = mac_mbuf_to_label(m);
MAC_IFNET_LOCK(ifp);

View File

@ -88,6 +88,16 @@ __FBSDID("$FreeBSD$");
* remote socket for UNIX domain sockets rather than keeping a local copy on
* this endpoint, but be cached and updated based on packets received for
* TCP/IP.
*
* Unlike with many other object types, the lock protecting MAC labels on
* sockets (the socket lock) is not frequently held at the points in code
* where socket-related checks are called. The MAC Framework acquires the
* lock over some entry points in order to enforce atomicity (such as label
* copies) but in other cases the policy modules will have to acquire the
* lock themselves if they use labels. This approach (a) avoids lock
* acquisitions when policies don't require labels and (b) solves a number of
* potential lock order issues when multiple sockets are used in the same
* entry point.
*/
struct label *
@ -234,13 +244,8 @@ void
mac_socket_newconn(struct socket *oldso, struct socket *newso)
{
if (mac_policy_count == 0)
return;
SOCK_LOCK(oldso);
MAC_POLICY_PERFORM_NOSLEEP(socket_newconn, oldso, oldso->so_label,
newso, newso->so_label);
SOCK_UNLOCK(oldso);
}
static void
@ -259,12 +264,13 @@ mac_socketpeer_set_from_mbuf(struct mbuf *m, struct socket *so)
{
struct label *label;
if (mac_policy_count == 0)
return;
label = mac_mbuf_to_label(m);
SOCK_LOCK(so);
MAC_POLICY_PERFORM_NOSLEEP(socketpeer_set_from_mbuf, m, label, so,
so->so_peerlabel);
SOCK_UNLOCK(so);
}
void
@ -274,15 +280,8 @@ mac_socketpeer_set_from_socket(struct socket *oldso, struct socket *newso)
if (mac_policy_count == 0)
return;
/*
* XXXRW: We want to hold locks on both sockets, but can't currently
* due to lock order -- opt to lock the socket where we're accessing
* so_label as it's more likely to change.
*/
SOCK_LOCK(oldso);
MAC_POLICY_PERFORM_NOSLEEP(socketpeer_set_from_socket, oldso,
oldso->so_label, newso, newso->so_peerlabel);
SOCK_UNLOCK(oldso);
}
void
@ -295,10 +294,8 @@ mac_socket_create_mbuf(struct socket *so, struct mbuf *m)
label = mac_mbuf_to_label(m);
SOCK_LOCK(so);
MAC_POLICY_PERFORM_NOSLEEP(socket_create_mbuf, so, so->so_label, m,
label);
SOCK_UNLOCK(so);
}
MAC_CHECK_PROBE_DEFINE2(socket_check_accept, "struct ucred *",
@ -309,14 +306,9 @@ mac_socket_check_accept(struct ucred *cred, struct socket *so)
{
int error;
if (mac_policy_count == 0)
return (0);
SOCK_LOCK(so);
MAC_POLICY_CHECK_NOSLEEP(socket_check_accept, cred, so,
so->so_label);
MAC_CHECK_PROBE2(socket_check_accept, error, cred, so);
SOCK_UNLOCK(so);
return (error);
}
@ -330,14 +322,9 @@ mac_socket_check_bind(struct ucred *cred, struct socket *so,
{
int error;
if (mac_policy_count == 0)
return (0);
SOCK_LOCK(so);
MAC_POLICY_CHECK_NOSLEEP(socket_check_bind, cred, so, so->so_label,
sa);
MAC_CHECK_PROBE3(socket_check_bind, error, cred, so, sa);
SOCK_UNLOCK(so);
return (error);
}
@ -351,14 +338,9 @@ mac_socket_check_connect(struct ucred *cred, struct socket *so,
{
int error;
if (mac_policy_count == 0)
return (0);
SOCK_LOCK(so);
MAC_POLICY_CHECK_NOSLEEP(socket_check_connect, cred, so,
so->so_label, sa);
MAC_CHECK_PROBE3(socket_check_connect, error, cred, so, sa);
SOCK_UNLOCK(so);
return (error);
}
@ -393,11 +375,9 @@ mac_socket_check_deliver(struct socket *so, struct mbuf *m)
label = mac_mbuf_to_label(m);
SOCK_LOCK(so);
MAC_POLICY_CHECK_NOSLEEP(socket_check_deliver, so, so->so_label, m,
label);
MAC_CHECK_PROBE2(socket_check_deliver, error, so, m);
SOCK_UNLOCK(so);
return (error);
}
@ -410,14 +390,9 @@ mac_socket_check_listen(struct ucred *cred, struct socket *so)
{
int error;
if (mac_policy_count == 0)
return (0);
SOCK_LOCK(so);
MAC_POLICY_CHECK_NOSLEEP(socket_check_listen, cred, so,
so->so_label);
MAC_CHECK_PROBE2(socket_check_listen, error, cred, so);
SOCK_UNLOCK(so);
return (error);
}
@ -430,13 +405,8 @@ mac_socket_check_poll(struct ucred *cred, struct socket *so)
{
int error;
if (mac_policy_count == 0)
return (0);
SOCK_LOCK(so);
MAC_POLICY_CHECK_NOSLEEP(socket_check_poll, cred, so, so->so_label);
MAC_CHECK_PROBE2(socket_check_poll, error, cred, so);
SOCK_UNLOCK(so);
return (error);
}
@ -449,14 +419,9 @@ mac_socket_check_receive(struct ucred *cred, struct socket *so)
{
int error;
if (mac_policy_count == 0)
return (0);
SOCK_LOCK(so);
MAC_POLICY_CHECK_NOSLEEP(socket_check_receive, cred, so,
so->so_label);
MAC_CHECK_PROBE2(socket_check_receive, error, cred, so);
SOCK_UNLOCK(so);
return (error);
}
@ -487,13 +452,8 @@ mac_socket_check_send(struct ucred *cred, struct socket *so)
{
int error;
if (mac_policy_count == 0)
return (0);
SOCK_LOCK(so);
MAC_POLICY_CHECK_NOSLEEP(socket_check_send, cred, so, so->so_label);
MAC_CHECK_PROBE2(socket_check_send, error, cred, so);
SOCK_UNLOCK(so);
return (error);
}
@ -506,13 +466,8 @@ mac_socket_check_stat(struct ucred *cred, struct socket *so)
{
int error;
if (mac_policy_count == 0)
return (0);
SOCK_LOCK(so);
MAC_POLICY_CHECK_NOSLEEP(socket_check_stat, cred, so, so->so_label);
MAC_CHECK_PROBE2(socket_check_stat, error, cred, so);
SOCK_UNLOCK(so);
return (error);
}
@ -525,14 +480,9 @@ mac_socket_check_visible(struct ucred *cred, struct socket *so)
{
int error;
if (mac_policy_count == 0)
return (0);
SOCK_LOCK(so);
MAC_POLICY_CHECK_NOSLEEP(socket_check_visible, cred, so,
so->so_label);
MAC_CHECK_PROBE2(socket_check_visible, error, cred, so);
SOCK_UNLOCK(so);
return (error);
}

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1999-2002, 2007-2008 Robert N. M. Watson
* Copyright (c) 1999-2002, 2007-2009 Robert N. M. Watson
* Copyright (c) 2001-2005 McAfee, Inc.
* Copyright (c) 2006 SPARTA, Inc.
* All rights reserved.
@ -1177,7 +1177,9 @@ biba_inpcb_create(struct socket *so, struct label *solabel,
source = SLOT(solabel);
dest = SLOT(inplabel);
SOCK_LOCK(so);
biba_copy_effective(source, dest);
SOCK_UNLOCK(so);
}
static void
@ -1198,6 +1200,8 @@ biba_inpcb_sosetlabel(struct socket *so, struct label *solabel,
{
struct mac_biba *source, *dest;
SOCK_LOCK_ASSERT(so);
source = SLOT(solabel);
dest = SLOT(inplabel);
@ -1918,6 +1922,7 @@ biba_socket_check_deliver(struct socket *so, struct label *solabel,
struct mbuf *m, struct label *mlabel)
{
struct mac_biba *p, *s;
int error;
if (!biba_enabled)
return (0);
@ -1925,7 +1930,10 @@ biba_socket_check_deliver(struct socket *so, struct label *solabel,
p = SLOT(mlabel);
s = SLOT(solabel);
return (biba_equal_effective(p, s) ? 0 : EACCES);
SOCK_LOCK(so);
error = biba_equal_effective(p, s) ? 0 : EACCES;
SOCK_UNLOCK(so);
return (error);
}
static int
@ -1935,6 +1943,8 @@ biba_socket_check_relabel(struct ucred *cred, struct socket *so,
struct mac_biba *subj, *obj, *new;
int error;
SOCK_LOCK_ASSERT(so);
new = SLOT(newlabel);
subj = SLOT(cred->cr_label);
obj = SLOT(solabel);
@ -1991,8 +2001,12 @@ biba_socket_check_visible(struct ucred *cred, struct socket *so,
subj = SLOT(cred->cr_label);
obj = SLOT(solabel);
if (!biba_dominate_effective(obj, subj))
SOCK_LOCK(so);
if (!biba_dominate_effective(obj, subj)) {
SOCK_UNLOCK(so);
return (ENOENT);
}
SOCK_UNLOCK(so);
return (0);
}
@ -2018,19 +2032,26 @@ biba_socket_create_mbuf(struct socket *so, struct label *solabel,
source = SLOT(solabel);
dest = SLOT(mlabel);
SOCK_LOCK(so);
biba_copy_effective(source, dest);
SOCK_UNLOCK(so);
}
static void
biba_socket_newconn(struct socket *oldso, struct label *oldsolabel,
struct socket *newso, struct label *newsolabel)
{
struct mac_biba *source, *dest;
struct mac_biba source, *dest;
SOCK_LOCK(oldso);
source = *SLOT(oldsolabel);
SOCK_UNLOCK(oldso);
source = SLOT(oldsolabel);
dest = SLOT(newsolabel);
biba_copy_effective(source, dest);
SOCK_LOCK(newso);
biba_copy_effective(&source, dest);
SOCK_UNLOCK(newso);
}
static void
@ -2039,6 +2060,8 @@ biba_socket_relabel(struct ucred *cred, struct socket *so,
{
struct mac_biba *source, *dest;
SOCK_LOCK_ASSERT(so);
source = SLOT(newlabel);
dest = SLOT(solabel);
@ -2054,7 +2077,9 @@ biba_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel,
source = SLOT(mlabel);
dest = SLOT(sopeerlabel);
SOCK_LOCK(so);
biba_copy_effective(source, dest);
SOCK_UNLOCK(so);
}
static void
@ -2062,12 +2087,16 @@ biba_socketpeer_set_from_socket(struct socket *oldso,
struct label *oldsolabel, struct socket *newso,
struct label *newsopeerlabel)
{
struct mac_biba *source, *dest;
struct mac_biba source, *dest;
source = SLOT(oldsolabel);
SOCK_LOCK(oldso);
source = *SLOT(oldsolabel);
SOCK_UNLOCK(oldso);
dest = SLOT(newsopeerlabel);
biba_copy_effective(source, dest);
SOCK_LOCK(newso);
biba_copy_effective(&source, dest);
SOCK_UNLOCK(newso);
}
static void

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1999-2002, 2007-2008 Robert N. M. Watson
* Copyright (c) 1999-2002, 2007-2009 Robert N. M. Watson
* Copyright (c) 2001-2005 Networks Associates Technology, Inc.
* Copyright (c) 2006 SPARTA, Inc.
* All rights reserved.
@ -1315,6 +1315,8 @@ lomac_inpcb_sosetlabel(struct socket *so, struct label *solabel,
{
struct mac_lomac *source, *dest;
SOCK_LOCK_ASSERT(so);
source = SLOT(solabel);
dest = SLOT(inplabel);
@ -1930,6 +1932,7 @@ lomac_socket_check_deliver(struct socket *so, struct label *solabel,
struct mbuf *m, struct label *mlabel)
{
struct mac_lomac *p, *s;
int error;
if (!lomac_enabled)
return (0);
@ -1937,7 +1940,10 @@ lomac_socket_check_deliver(struct socket *so, struct label *solabel,
p = SLOT(mlabel);
s = SLOT(solabel);
return (lomac_equal_single(p, s) ? 0 : EACCES);
SOCK_LOCK(so);
error = lomac_equal_single(p, s) ? 0 : EACCES;
SOCK_UNLOCK(so);
return (error);
}
static int
@ -1947,6 +1953,8 @@ lomac_socket_check_relabel(struct ucred *cred, struct socket *so,
struct mac_lomac *subj, *obj, *new;
int error;
SOCK_LOCK_ASSERT(so);
new = SLOT(newlabel);
subj = SLOT(cred->cr_label);
obj = SLOT(solabel);
@ -2003,8 +2011,12 @@ lomac_socket_check_visible(struct ucred *cred, struct socket *so,
subj = SLOT(cred->cr_label);
obj = SLOT(solabel);
if (!lomac_dominate_single(obj, subj))
SOCK_LOCK(so);
if (!lomac_dominate_single(obj, subj)) {
SOCK_UNLOCK(so);
return (ENOENT);
}
SOCK_UNLOCK(so);
return (0);
}
@ -2030,19 +2042,26 @@ lomac_socket_create_mbuf(struct socket *so, struct label *solabel,
source = SLOT(solabel);
dest = SLOT(mlabel);
SOCK_LOCK(so);
lomac_copy_single(source, dest);
SOCK_UNLOCK(so);
}
static void
lomac_socket_newconn(struct socket *oldso, struct label *oldsolabel,
struct socket *newso, struct label *newsolabel)
{
struct mac_lomac *source, *dest;
struct mac_lomac source, *dest;
SOCK_LOCK(oldso);
source = *SLOT(oldsolabel);
SOCK_UNLOCK(oldso);
source = SLOT(oldsolabel);
dest = SLOT(newsolabel);
lomac_copy_single(source, dest);
SOCK_LOCK(newso);
lomac_copy_single(&source, dest);
SOCK_UNLOCK(newso);
}
static void
@ -2051,6 +2070,8 @@ lomac_socket_relabel(struct ucred *cred, struct socket *so,
{
struct mac_lomac *source, *dest;
SOCK_LOCK_ASSERT(so);
source = SLOT(newlabel);
dest = SLOT(solabel);
@ -2066,7 +2087,9 @@ lomac_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel,
source = SLOT(mlabel);
dest = SLOT(sopeerlabel);
SOCK_LOCK(so);
lomac_copy_single(source, dest);
SOCK_UNLOCK(so);
}
static void
@ -2074,12 +2097,17 @@ lomac_socketpeer_set_from_socket(struct socket *oldso,
struct label *oldsolabel, struct socket *newso,
struct label *newsopeerlabel)
{
struct mac_lomac *source, *dest;
struct mac_lomac source, *dest;
SOCK_LOCK(oldso);
source = *SLOT(oldsolabel);
SOCK_UNLOCK(oldso);
source = SLOT(oldsolabel);
dest = SLOT(newsopeerlabel);
lomac_copy_single(source, dest);
SOCK_LOCK(newso);
lomac_copy_single(&source, dest);
SOCK_UNLOCK(newso);
}
static void

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1999-2002, 2007-2008 Robert N. M. Watson
* Copyright (c) 1999-2002, 2007-2009 Robert N. M. Watson
* Copyright (c) 2001-2005 McAfee, Inc.
* Copyright (c) 2006 SPARTA, Inc.
* All rights reserved.
@ -1116,6 +1116,8 @@ mls_inpcb_sosetlabel(struct socket *so, struct label *solabel,
{
struct mac_mls *source, *dest;
SOCK_LOCK_ASSERT(so);
source = SLOT(solabel);
dest = SLOT(inplabel);
@ -1623,6 +1625,7 @@ mls_socket_check_deliver(struct socket *so, struct label *solabel,
struct mbuf *m, struct label *mlabel)
{
struct mac_mls *p, *s;
int error;
if (!mls_enabled)
return (0);
@ -1630,7 +1633,11 @@ mls_socket_check_deliver(struct socket *so, struct label *solabel,
p = SLOT(mlabel);
s = SLOT(solabel);
return (mls_equal_effective(p, s) ? 0 : EACCES);
SOCK_LOCK(so);
error = mls_equal_effective(p, s) ? 0 : EACCES;
SOCK_UNLOCK(so);
return (error);
}
static int
@ -1640,6 +1647,8 @@ mls_socket_check_relabel(struct ucred *cred, struct socket *so,
struct mac_mls *subj, *obj, *new;
int error;
SOCK_LOCK_ASSERT(so);
new = SLOT(newlabel);
subj = SLOT(cred->cr_label);
obj = SLOT(solabel);
@ -1696,8 +1705,12 @@ mls_socket_check_visible(struct ucred *cred, struct socket *so,
subj = SLOT(cred->cr_label);
obj = SLOT(solabel);
if (!mls_dominate_effective(subj, obj))
SOCK_LOCK(so);
if (!mls_dominate_effective(subj, obj)) {
SOCK_UNLOCK(so);
return (ENOENT);
}
SOCK_UNLOCK(so);
return (0);
}
@ -1723,19 +1736,26 @@ mls_socket_create_mbuf(struct socket *so, struct label *solabel,
source = SLOT(solabel);
dest = SLOT(mlabel);
SOCK_LOCK(so);
mls_copy_effective(source, dest);
SOCK_UNLOCK(so);
}
static void
mls_socket_newconn(struct socket *oldso, struct label *oldsolabel,
struct socket *newso, struct label *newsolabel)
{
struct mac_mls *source, *dest;
struct mac_mls source, *dest;
SOCK_LOCK(oldso);
source = *SLOT(oldsolabel);
SOCK_UNLOCK(oldso);
source = SLOT(oldsolabel);
dest = SLOT(newsolabel);
mls_copy_effective(source, dest);
SOCK_LOCK(newso);
mls_copy_effective(&source, dest);
SOCK_UNLOCK(newso);
}
static void
@ -1744,6 +1764,8 @@ mls_socket_relabel(struct ucred *cred, struct socket *so,
{
struct mac_mls *source, *dest;
SOCK_LOCK_ASSERT(so);
source = SLOT(newlabel);
dest = SLOT(solabel);
@ -1759,7 +1781,9 @@ mls_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel,
source = SLOT(mlabel);
dest = SLOT(sopeerlabel);
SOCK_LOCK(so);
mls_copy_effective(source, dest);
SOCK_UNLOCK(so);
}
static void
@ -1767,12 +1791,17 @@ mls_socketpeer_set_from_socket(struct socket *oldso,
struct label *oldsolabel, struct socket *newso,
struct label *newsopeerlabel)
{
struct mac_mls *source, *dest;
struct mac_mls source, *dest;
SOCK_LOCK(oldso);
source = *SLOT(oldsolabel);
SOCK_UNLOCK(oldso);
source = SLOT(oldsolabel);
dest = SLOT(newsopeerlabel);
mls_copy_effective(source, dest);
SOCK_LOCK(newso);
mls_copy_effective(&source, dest);
SOCK_UNLOCK(newso);
}
static void

View File

@ -413,6 +413,8 @@ stub_inpcb_sosetlabel(struct socket *so, struct label *solabel,
struct inpcb *inp, struct label *inplabel)
{
SOCK_LOCK_ASSERT(so);
}
static void
@ -809,6 +811,11 @@ stub_socket_check_accept(struct ucred *cred, struct socket *so,
struct label *solabel)
{
#if 0
SOCK_LOCK(so);
SOCK_UNLOCK(so);
#endif
return (0);
}
@ -817,6 +824,11 @@ stub_socket_check_bind(struct ucred *cred, struct socket *so,
struct label *solabel, struct sockaddr *sa)
{
#if 0
SOCK_LOCK(so);
SOCK_UNLOCK(so);
#endif
return (0);
}
@ -825,6 +837,11 @@ stub_socket_check_connect(struct ucred *cred, struct socket *so,
struct label *solabel, struct sockaddr *sa)
{
#if 0
SOCK_LOCK(so);
SOCK_UNLOCK(so);
#endif
return (0);
}
@ -840,6 +857,11 @@ stub_socket_check_deliver(struct socket *so, struct label *solabel,
struct mbuf *m, struct label *mlabel)
{
#if 0
SOCK_LOCK(so);
SOCK_UNLOCK(so);
#endif
return (0);
}
@ -848,6 +870,11 @@ stub_socket_check_listen(struct ucred *cred, struct socket *so,
struct label *solabel)
{
#if 0
SOCK_LOCK(so);
SOCK_UNLOCK(so);
#endif
return (0);
}
@ -856,6 +883,11 @@ stub_socket_check_poll(struct ucred *cred, struct socket *so,
struct label *solabel)
{
#if 0
SOCK_LOCK(so);
SOCK_UNLOCK(so);
#endif
return (0);
}
@ -864,6 +896,11 @@ stub_socket_check_receive(struct ucred *cred, struct socket *so,
struct label *solabel)
{
#if 0
SOCK_LOCK(so);
SOCK_UNLOCK(so);
#endif
return (0);
}
@ -872,6 +909,8 @@ stub_socket_check_relabel(struct ucred *cred, struct socket *so,
struct label *solabel, struct label *newlabel)
{
SOCK_LOCK_ASSERT(so);
return (0);
}
static int
@ -879,6 +918,11 @@ stub_socket_check_send(struct ucred *cred, struct socket *so,
struct label *solabel)
{
#if 0
SOCK_LOCK(so);
SOCK_UNLOCK(so);
#endif
return (0);
}
@ -887,6 +931,11 @@ stub_socket_check_stat(struct ucred *cred, struct socket *so,
struct label *solabel)
{
#if 0
SOCK_LOCK(so);
SOCK_UNLOCK(so);
#endif
return (0);
}
@ -903,6 +952,11 @@ stub_socket_check_visible(struct ucred *cred, struct socket *so,
struct label *solabel)
{
#if 0
SOCK_LOCK(so);
SOCK_UNLOCK(so);
#endif
return (0);
}
@ -918,6 +972,10 @@ stub_socket_create_mbuf(struct socket *so, struct label *solabel,
struct mbuf *m, struct label *mlabel)
{
#if 0
SOCK_LOCK(so);
SOCK_UNLOCK(so);
#endif
}
static void
@ -925,6 +983,14 @@ stub_socket_newconn(struct socket *oldso, struct label *oldsolabel,
struct socket *newso, struct label *newsolabel)
{
#if 0
SOCK_LOCK(oldso);
SOCK_UNLOCK(oldso);
#endif
#if 0
SOCK_LOCK(newso);
SOCK_UNLOCK(newso);
#endif
}
static void
@ -932,6 +998,7 @@ stub_socket_relabel(struct ucred *cred, struct socket *so,
struct label *solabel, struct label *newlabel)
{
SOCK_LOCK_ASSERT(so);
}
static void
@ -939,6 +1006,10 @@ stub_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel,
struct socket *so, struct label *sopeerlabel)
{
#if 0
SOCK_LOCK(so);
SOCK_UNLOCK(so);
#endif
}
static void
@ -947,6 +1018,14 @@ stub_socketpeer_set_from_socket(struct socket *oldso,
struct label *newsopeerlabel)
{
#if 0
SOCK_LOCK(oldso);
SOCK_UNLOCK(oldso);
#endif
#if 0
SOCK_LOCK(newso);
SOCK_UNLOCK(newso);
#endif
}
static void

View File

@ -671,7 +671,9 @@ test_inpcb_create(struct socket *so, struct label *solabel,
struct inpcb *inp, struct label *inplabel)
{
SOCK_LOCK(so);
LABEL_CHECK(solabel, MAGIC_SOCKET);
SOCK_UNLOCK(so);
LABEL_CHECK(inplabel, MAGIC_INPCB);
COUNTER_INC(inpcb_create);
}
@ -717,6 +719,8 @@ test_inpcb_sosetlabel(struct socket *so, struct label *solabel,
struct inpcb *inp, struct label *inplabel)
{
SOCK_LOCK_ASSERT(so);
LABEL_CHECK(solabel, MAGIC_SOCKET);
LABEL_CHECK(inplabel, MAGIC_INPCB);
COUNTER_INC(inpcb_sosetlabel);
@ -1526,7 +1530,9 @@ test_socket_check_accept(struct ucred *cred, struct socket *so,
{
LABEL_CHECK(cred->cr_label, MAGIC_CRED);
SOCK_LOCK(so);
LABEL_CHECK(solabel, MAGIC_SOCKET);
SOCK_UNLOCK(so);
COUNTER_INC(socket_check_accept);
return (0);
@ -1539,7 +1545,9 @@ test_socket_check_bind(struct ucred *cred, struct socket *so,
{
LABEL_CHECK(cred->cr_label, MAGIC_CRED);
SOCK_LOCK(so);
LABEL_CHECK(solabel, MAGIC_SOCKET);
SOCK_UNLOCK(so);
COUNTER_INC(socket_check_bind);
return (0);
@ -1552,7 +1560,9 @@ test_socket_check_connect(struct ucred *cred, struct socket *so,
{
LABEL_CHECK(cred->cr_label, MAGIC_CRED);
SOCK_LOCK(so);
LABEL_CHECK(solabel, MAGIC_SOCKET);
SOCK_UNLOCK(so);
COUNTER_INC(socket_check_connect);
return (0);
@ -1564,7 +1574,9 @@ test_socket_check_deliver(struct socket *so, struct label *solabel,
struct mbuf *m, struct label *mlabel)
{
SOCK_LOCK(so);
LABEL_CHECK(solabel, MAGIC_SOCKET);
SOCK_UNLOCK(so);
LABEL_CHECK(mlabel, MAGIC_MBUF);
COUNTER_INC(socket_check_deliver);
@ -1578,7 +1590,9 @@ test_socket_check_listen(struct ucred *cred, struct socket *so,
{
LABEL_CHECK(cred->cr_label, MAGIC_CRED);
SOCK_LOCK(so);
LABEL_CHECK(solabel, MAGIC_SOCKET);
SOCK_UNLOCK(so);
COUNTER_INC(socket_check_listen);
return (0);
@ -1591,7 +1605,9 @@ test_socket_check_poll(struct ucred *cred, struct socket *so,
{
LABEL_CHECK(cred->cr_label, MAGIC_CRED);
SOCK_LOCK(so);
LABEL_CHECK(solabel, MAGIC_SOCKET);
SOCK_UNLOCK(so);
COUNTER_INC(socket_check_poll);
return (0);
@ -1604,7 +1620,9 @@ test_socket_check_receive(struct ucred *cred, struct socket *so,
{
LABEL_CHECK(cred->cr_label, MAGIC_CRED);
SOCK_LOCK(so);
LABEL_CHECK(solabel, MAGIC_SOCKET);
SOCK_UNLOCK(so);
COUNTER_INC(socket_check_receive);
return (0);
@ -1616,6 +1634,8 @@ test_socket_check_relabel(struct ucred *cred, struct socket *so,
struct label *solabel, struct label *newlabel)
{
SOCK_LOCK_ASSERT(so);
LABEL_CHECK(cred->cr_label, MAGIC_CRED);
LABEL_CHECK(solabel, MAGIC_SOCKET);
LABEL_CHECK(newlabel, MAGIC_SOCKET);
@ -1631,7 +1651,9 @@ test_socket_check_send(struct ucred *cred, struct socket *so,
{
LABEL_CHECK(cred->cr_label, MAGIC_CRED);
SOCK_LOCK(so);
LABEL_CHECK(solabel, MAGIC_SOCKET);
SOCK_UNLOCK(so);
COUNTER_INC(socket_check_send);
return (0);
@ -1644,7 +1666,9 @@ test_socket_check_stat(struct ucred *cred, struct socket *so,
{
LABEL_CHECK(cred->cr_label, MAGIC_CRED);
SOCK_LOCK(so);
LABEL_CHECK(solabel, MAGIC_SOCKET);
SOCK_UNLOCK(so);
COUNTER_INC(socket_check_stat);
return (0);
@ -1657,7 +1681,9 @@ test_socket_check_visible(struct ucred *cred, struct socket *so,
{
LABEL_CHECK(cred->cr_label, MAGIC_CRED);
SOCK_LOCK(so);
LABEL_CHECK(solabel, MAGIC_SOCKET);
SOCK_UNLOCK(so);
COUNTER_INC(socket_check_visible);
return (0);
@ -1686,11 +1712,13 @@ test_socket_create(struct ucred *cred, struct socket *so,
COUNTER_DECL(socket_create_mbuf);
static void
test_socket_create_mbuf(struct socket *so, struct label *socketlabel,
test_socket_create_mbuf(struct socket *so, struct label *solabel,
struct mbuf *m, struct label *mlabel)
{
LABEL_CHECK(socketlabel, MAGIC_SOCKET);
SOCK_LOCK(so);
LABEL_CHECK(solabel, MAGIC_SOCKET);
SOCK_UNLOCK(so);
LABEL_CHECK(mlabel, MAGIC_MBUF);
COUNTER_INC(socket_create_mbuf);
}
@ -1749,8 +1777,12 @@ test_socket_newconn(struct socket *oldso, struct label *oldsolabel,
struct socket *newso, struct label *newsolabel)
{
SOCK_LOCK(oldso);
LABEL_CHECK(oldsolabel, MAGIC_SOCKET);
SOCK_UNLOCK(oldso);
SOCK_LOCK(newso);
LABEL_CHECK(newsolabel, MAGIC_SOCKET);
SOCK_UNLOCK(newso);
COUNTER_INC(socket_newconn);
}
@ -1760,6 +1792,8 @@ test_socket_relabel(struct ucred *cred, struct socket *so,
struct label *solabel, struct label *newlabel)
{
SOCK_LOCK_ASSERT(so);
LABEL_CHECK(cred->cr_label, MAGIC_CRED);
LABEL_CHECK(solabel, MAGIC_SOCKET);
LABEL_CHECK(newlabel, MAGIC_SOCKET);
@ -1805,11 +1839,13 @@ test_socketpeer_init_label(struct label *label, int flag)
COUNTER_DECL(socketpeer_set_from_mbuf);
static void
test_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel,
struct socket *socket, struct label *socketpeerlabel)
struct socket *so, struct label *sopeerlabel)
{
LABEL_CHECK(mlabel, MAGIC_MBUF);
LABEL_CHECK(socketpeerlabel, MAGIC_SOCKET);
SOCK_LOCK(so);
LABEL_CHECK(sopeerlabel, MAGIC_SOCKET);
SOCK_UNLOCK(so);
COUNTER_INC(socketpeer_set_from_mbuf);
}
@ -1820,8 +1856,12 @@ test_socketpeer_set_from_socket(struct socket *oldso,
struct label *newsopeerlabel)
{
SOCK_LOCK(oldso);
LABEL_CHECK(oldsolabel, MAGIC_SOCKET);
SOCK_UNLOCK(oldso);
SOCK_LOCK(newso);
LABEL_CHECK(newsopeerlabel, MAGIC_SOCKET);
SOCK_UNLOCK(newso);
COUNTER_INC(socketpeer_set_from_socket);
}