diff options
author | rwatson <rwatson@FreeBSD.org> | 2009-06-02 18:26:17 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2009-06-02 18:26:17 +0000 |
commit | 0f9e85844038f1065732f6e28261101bb0c61492 (patch) | |
tree | 9f93a531fd61b5932ab6fcc38f6915b3f1a0ab60 /sys/security/mac/mac_socket.c | |
parent | 12453fdf4f537f30c14a82fa93b74dd48d24775b (diff) | |
download | FreeBSD-src-0f9e85844038f1065732f6e28261101bb0c61492.zip FreeBSD-src-0f9e85844038f1065732f6e28261101bb0c61492.tar.gz |
Add internal 'mac_policy_count' counter to the MAC Framework, which is a
count of the number of registered policies.
Rather than unconditionally locking sockets before passing them into MAC,
lock them in the MAC entry points only if mac_policy_count is non-zero.
This avoids locking overhead for a number of socket system calls when no
policies are registered, eliminating measurable overhead for the MAC
Framework for the socket subsystem when there are no active policies.
Possibly socket locks should be acquired by policies if they are required
for socket labels, which would further avoid locking overhead when there
are policies but they don't require labeling of sockets, or possibly
don't even implement socket controls.
Obtained from: TrustedBSD Project
Diffstat (limited to 'sys/security/mac/mac_socket.c')
-rw-r--r-- | sys/security/mac/mac_socket.c | 75 |
1 files changed, 58 insertions, 17 deletions
diff --git a/sys/security/mac/mac_socket.c b/sys/security/mac/mac_socket.c index 25f8dae..704c60b 100644 --- a/sys/security/mac/mac_socket.c +++ b/sys/security/mac/mac_socket.c @@ -234,10 +234,13 @@ void mac_socket_newconn(struct socket *oldso, struct socket *newso) { - SOCK_LOCK_ASSERT(oldso); + 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 @@ -256,25 +259,30 @@ mac_socketpeer_set_from_mbuf(struct mbuf *m, struct socket *so) { struct label *label; - SOCK_LOCK_ASSERT(so); - 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 mac_socketpeer_set_from_socket(struct socket *oldso, struct socket *newso) { + + if (mac_policy_count == 0) + return; /* - * XXXRW: only hold the socket lock on one at a time, as one socket - * is the original, and one is the new. However, it's called in both - * directions, so we can't assert the lock here currently. + * 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 @@ -282,12 +290,15 @@ mac_socket_create_mbuf(struct socket *so, struct mbuf *m) { struct label *label; - SOCK_LOCK_ASSERT(so); + if (mac_policy_count == 0) + return; 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 *", @@ -298,11 +309,14 @@ mac_socket_check_accept(struct ucred *cred, struct socket *so) { int error; - SOCK_LOCK_ASSERT(so); + 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); } @@ -316,11 +330,14 @@ mac_socket_check_bind(struct ucred *cred, struct socket *so, { int error; - SOCK_LOCK_ASSERT(so); + 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); } @@ -334,11 +351,14 @@ mac_socket_check_connect(struct ucred *cred, struct socket *so, { int error; - SOCK_LOCK_ASSERT(so); + 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); } @@ -368,13 +388,16 @@ mac_socket_check_deliver(struct socket *so, struct mbuf *m) struct label *label; int error; - SOCK_LOCK_ASSERT(so); + if (mac_policy_count == 0) + return (0); 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); } @@ -387,11 +410,14 @@ mac_socket_check_listen(struct ucred *cred, struct socket *so) { int error; - SOCK_LOCK_ASSERT(so); + 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); } @@ -404,10 +430,13 @@ mac_socket_check_poll(struct ucred *cred, struct socket *so) { int error; - SOCK_LOCK_ASSERT(so); + 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); } @@ -420,11 +449,14 @@ mac_socket_check_receive(struct ucred *cred, struct socket *so) { int error; - SOCK_LOCK_ASSERT(so); + 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); } @@ -455,10 +487,13 @@ mac_socket_check_send(struct ucred *cred, struct socket *so) { int error; - SOCK_LOCK_ASSERT(so); + 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); } @@ -471,10 +506,13 @@ mac_socket_check_stat(struct ucred *cred, struct socket *so) { int error; - SOCK_LOCK_ASSERT(so); + 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); } @@ -487,11 +525,14 @@ mac_socket_check_visible(struct ucred *cred, struct socket *so) { int error; - SOCK_LOCK_ASSERT(so); + 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); } |