aboutsummaryrefslogtreecommitdiff
path: root/sys/security
diff options
context:
space:
mode:
authorRobert Watson <rwatson@FreeBSD.org>2009-06-02 18:26:17 +0000
committerRobert Watson <rwatson@FreeBSD.org>2009-06-02 18:26:17 +0000
commitf93bfb23dcb5b1d8a3aa13da522369974fcda39b (patch)
tree9f93a531fd61b5932ab6fcc38f6915b3f1a0ab60 /sys/security
parentfd02a3b5c966582744a3fbdcfab9d8c3fd5f7436 (diff)
downloadsrc-f93bfb23dcb5b1d8a3aa13da522369974fcda39b.tar.gz
src-f93bfb23dcb5b1d8a3aa13da522369974fcda39b.zip
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
Notes
Notes: svn path=/head/; revision=193332
Diffstat (limited to 'sys/security')
-rw-r--r--sys/security/mac/mac_framework.c16
-rw-r--r--sys/security/mac/mac_internal.h1
-rw-r--r--sys/security/mac/mac_socket.c75
3 files changed, 70 insertions, 22 deletions
diff --git a/sys/security/mac/mac_framework.c b/sys/security/mac/mac_framework.c
index 6f675cb4cae8..3d2a1395823c 100644
--- a/sys/security/mac/mac_framework.c
+++ b/sys/security/mac/mac_framework.c
@@ -179,6 +179,7 @@ static struct sx mac_policy_sx; /* Sleeping entry points. */
struct mac_policy_list_head mac_policy_list;
struct mac_policy_list_head mac_static_policy_list;
+u_int mac_policy_count; /* Registered policy count. */
static void mac_policy_xlock(void);
static void mac_policy_xlock_assert(void);
@@ -351,17 +352,22 @@ mac_policy_getlabeled(struct mac_policy_conf *mpc)
* requiring labels across all policies.
*/
static void
-mac_policy_updateflags(void)
+mac_policy_update(void)
{
struct mac_policy_conf *mpc;
mac_policy_xlock_assert();
mac_labeled = 0;
- LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list)
+ mac_policy_count = 0;
+ LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) {
mac_labeled |= mac_policy_getlabeled(mpc);
- LIST_FOREACH(mpc, &mac_policy_list, mpc_list)
+ mac_policy_count++;
+ }
+ LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {
mac_labeled |= mac_policy_getlabeled(mpc);
+ mac_policy_count++;
+ }
}
static int
@@ -434,7 +440,7 @@ mac_policy_register(struct mac_policy_conf *mpc)
*/
if (mpc->mpc_ops->mpo_init != NULL)
(*(mpc->mpc_ops->mpo_init))(mpc);
- mac_policy_updateflags();
+ mac_policy_update();
SDT_PROBE(mac, kernel, policy, register, mpc, 0, 0, 0, 0);
printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname,
@@ -480,7 +486,7 @@ mac_policy_unregister(struct mac_policy_conf *mpc)
LIST_REMOVE(mpc, mpc_list);
mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED;
- mac_policy_updateflags();
+ mac_policy_update();
mac_policy_xunlock();
SDT_PROBE(mac, kernel, policy, unregister, mpc, 0, 0, 0, 0);
diff --git a/sys/security/mac/mac_internal.h b/sys/security/mac/mac_internal.h
index 45bd52459d40..39fc4042beb5 100644
--- a/sys/security/mac/mac_internal.h
+++ b/sys/security/mac/mac_internal.h
@@ -189,6 +189,7 @@ struct label {
*/
extern struct mac_policy_list_head mac_policy_list;
extern struct mac_policy_list_head mac_static_policy_list;
+extern u_int mac_policy_count;
extern uint64_t mac_labeled;
extern struct mtx mac_ifnet_mtx;
diff --git a/sys/security/mac/mac_socket.c b/sys/security/mac/mac_socket.c
index 25f8dae2d551..704c60bf2df1 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);
}