diff options
author | rwatson <rwatson@FreeBSD.org> | 2009-03-14 16:06:06 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2009-03-14 16:06:06 +0000 |
commit | 874a1578bb8d1d47508c0fab69ef796bed233686 (patch) | |
tree | a0703274e6f642c1143773213e750b20510252bc /sys | |
parent | 7f1b26ac0cda36f28a34c828f3295d040943c70b (diff) | |
download | FreeBSD-src-874a1578bb8d1d47508c0fab69ef796bed233686.zip FreeBSD-src-874a1578bb8d1d47508c0fab69ef796bed233686.tar.gz |
Rework MAC Framework synchronization in a number of ways in order to
improve performance:
- Eliminate custom reference count and condition variable to monitor
threads entering the framework, as this had both significant overhead
and behaved badly in the face of contention.
- Replace reference count with two locks: an rwlock and an sx lock,
which will be read-acquired by threads entering the framework
depending on whether a give policy entry point is permitted to sleep
or not.
- Replace previous mutex locking of the reference count for exclusive
access with write acquiring of both the policy list sx and rw locks,
which occurs only when policies are attached or detached.
- Do a lockless read of the dynamic policy list head before acquiring
any locks in order to reduce overhead when no dynamic policies are
loaded; this a race we can afford to lose.
- For every policy entry point invocation, decide whether sleeping is
permitted, and if not, use a _NOSLEEP() variant of the composition
macros, which will use the rwlock instead of the sxlock. In some
cases, we decide which to use based on allocation flags passed to the
MAC Framework entry point.
As with the move to rwlocks/rmlocks in pfil, this may trigger witness
warnings, but these should (generally) be false positives as all
acquisition of the locks is for read with two very narrow exceptions
for policy load/unload, and those code blocks should never acquire
other locks.
Sponsored by: Google, Inc.
Obtained from: TrustedBSD Project
Discussed with: csjp (idea, not specific patch)
Diffstat (limited to 'sys')
-rw-r--r-- | sys/security/mac/mac_atalk.c | 8 | ||||
-rw-r--r-- | sys/security/mac/mac_audit.c | 10 | ||||
-rw-r--r-- | sys/security/mac/mac_cred.c | 34 | ||||
-rw-r--r-- | sys/security/mac/mac_framework.c | 185 | ||||
-rw-r--r-- | sys/security/mac/mac_inet.c | 73 | ||||
-rw-r--r-- | sys/security/mac/mac_inet6.c | 25 | ||||
-rw-r--r-- | sys/security/mac/mac_internal.h | 99 | ||||
-rw-r--r-- | sys/security/mac/mac_net.c | 39 | ||||
-rw-r--r-- | sys/security/mac/mac_pipe.c | 22 | ||||
-rw-r--r-- | sys/security/mac/mac_posix_sem.c | 18 | ||||
-rw-r--r-- | sys/security/mac/mac_posix_shm.c | 19 | ||||
-rw-r--r-- | sys/security/mac/mac_priv.c | 4 | ||||
-rw-r--r-- | sys/security/mac/mac_process.c | 10 | ||||
-rw-r--r-- | sys/security/mac/mac_socket.c | 60 | ||||
-rw-r--r-- | sys/security/mac/mac_syscalls.c | 12 | ||||
-rw-r--r-- | sys/security/mac/mac_system.c | 14 | ||||
-rw-r--r-- | sys/security/mac/mac_sysv_msg.c | 31 | ||||
-rw-r--r-- | sys/security/mac/mac_sysv_sem.c | 17 | ||||
-rw-r--r-- | sys/security/mac/mac_sysv_shm.c | 22 | ||||
-rw-r--r-- | sys/security/mac/mac_vfs.c | 35 |
20 files changed, 410 insertions, 327 deletions
diff --git a/sys/security/mac/mac_atalk.c b/sys/security/mac/mac_atalk.c index 0992ee5..d45d29c 100644 --- a/sys/security/mac/mac_atalk.c +++ b/sys/security/mac/mac_atalk.c @@ -1,9 +1,12 @@ /*- - * Copyright (c) 2007 Robert N. M. Watson + * Copyright (c) 2007-2009 Robert N. M. Watson * All rights reserved. * * This software was developed by Robert Watson for the TrustedBSD Project. * + * This software was developed at the University of Cambridge Computer + * Laboratory with support from a grant from Google, Inc. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -61,6 +64,7 @@ mac_netatalk_aarp_send(struct ifnet *ifp, struct mbuf *m) mlabel = mac_mbuf_to_label(m); MAC_IFNET_LOCK(ifp); - MAC_PERFORM(netatalk_aarp_send, ifp, ifp->if_label, m, mlabel); + MAC_PERFORM_NOSLEEP(netatalk_aarp_send, ifp, ifp->if_label, m, + mlabel); MAC_IFNET_UNLOCK(ifp); } diff --git a/sys/security/mac/mac_audit.c b/sys/security/mac/mac_audit.c index 9bc2e27..62cfbdf 100644 --- a/sys/security/mac/mac_audit.c +++ b/sys/security/mac/mac_audit.c @@ -66,7 +66,7 @@ mac_cred_check_setaudit(struct ucred *cred, struct auditinfo *ai) { int error; - MAC_CHECK(cred_check_setaudit, cred, ai); + MAC_CHECK_NOSLEEP(cred_check_setaudit, cred, ai); MAC_CHECK_PROBE2(cred_check_setaudit, error, cred, ai); return (error); @@ -80,7 +80,7 @@ mac_cred_check_setaudit_addr(struct ucred *cred, struct auditinfo_addr *aia) { int error; - MAC_CHECK(cred_check_setaudit_addr, cred, aia); + MAC_CHECK_NOSLEEP(cred_check_setaudit_addr, cred, aia); MAC_CHECK_PROBE2(cred_check_setaudit_addr, error, cred, aia); return (error); @@ -93,7 +93,7 @@ mac_cred_check_setauid(struct ucred *cred, uid_t auid) { int error; - MAC_CHECK(cred_check_setauid, cred, auid); + MAC_CHECK_NOSLEEP(cred_check_setauid, cred, auid); MAC_CHECK_PROBE2(cred_check_setauid, error, cred, auid); return (error); @@ -107,7 +107,7 @@ mac_system_check_audit(struct ucred *cred, void *record, int length) { int error; - MAC_CHECK(system_check_audit, cred, record, length); + MAC_CHECK_NOSLEEP(system_check_audit, cred, record, length); MAC_CHECK_PROBE3(system_check_audit, error, cred, record, length); return (error); @@ -138,7 +138,7 @@ mac_system_check_auditon(struct ucred *cred, int cmd) { int error; - MAC_CHECK(system_check_auditon, cred, cmd); + MAC_CHECK_NOSLEEP(system_check_auditon, cred, cmd); MAC_CHECK_PROBE2(system_check_auditon, error, cred, cmd); return (error); diff --git a/sys/security/mac/mac_cred.c b/sys/security/mac/mac_cred.c index 41c6e66..b6dcf9d 100644 --- a/sys/security/mac/mac_cred.c +++ b/sys/security/mac/mac_cred.c @@ -100,7 +100,7 @@ void mac_cred_label_free(struct label *label) { - MAC_PERFORM(cred_destroy_label, label); + MAC_PERFORM_NOSLEEP(cred_destroy_label, label); mac_labelzone_free(label); } @@ -127,7 +127,7 @@ void mac_cred_associate_nfsd(struct ucred *cred) { - MAC_PERFORM(cred_associate_nfsd, cred); + MAC_PERFORM_NOSLEEP(cred_associate_nfsd, cred); } /* @@ -138,7 +138,7 @@ void mac_cred_create_swapper(struct ucred *cred) { - MAC_PERFORM(cred_create_swapper, cred); + MAC_PERFORM_NOSLEEP(cred_create_swapper, cred); } /* @@ -149,7 +149,7 @@ void mac_cred_create_init(struct ucred *cred) { - MAC_PERFORM(cred_create_init, cred); + MAC_PERFORM_NOSLEEP(cred_create_init, cred); } int @@ -182,7 +182,7 @@ void mac_cred_copy(struct ucred *src, struct ucred *dest) { - MAC_PERFORM(cred_copy_label, src->cr_label, dest->cr_label); + MAC_PERFORM_NOSLEEP(cred_copy_label, src->cr_label, dest->cr_label); } /* @@ -194,7 +194,7 @@ void mac_cred_relabel(struct ucred *cred, struct label *newlabel) { - MAC_PERFORM(cred_relabel, cred, newlabel); + MAC_PERFORM_NOSLEEP(cred_relabel, cred, newlabel); } MAC_CHECK_PROBE_DEFINE2(cred_check_relabel, "struct ucred *", @@ -205,7 +205,7 @@ mac_cred_check_relabel(struct ucred *cred, struct label *newlabel) { int error; - MAC_CHECK(cred_check_relabel, cred, newlabel); + MAC_CHECK_NOSLEEP(cred_check_relabel, cred, newlabel); MAC_CHECK_PROBE2(cred_check_relabel, error, cred, newlabel); return (error); @@ -218,7 +218,7 @@ mac_cred_check_setuid(struct ucred *cred, uid_t uid) { int error; - MAC_CHECK(cred_check_setuid, cred, uid); + MAC_CHECK_NOSLEEP(cred_check_setuid, cred, uid); MAC_CHECK_PROBE2(cred_check_setuid, error, cred, uid); return (error); @@ -231,7 +231,7 @@ mac_cred_check_seteuid(struct ucred *cred, uid_t euid) { int error; - MAC_CHECK(cred_check_seteuid, cred, euid); + MAC_CHECK_NOSLEEP(cred_check_seteuid, cred, euid); MAC_CHECK_PROBE2(cred_check_seteuid, error, cred, euid); return (error); @@ -244,7 +244,7 @@ mac_cred_check_setgid(struct ucred *cred, gid_t gid) { int error; - MAC_CHECK(cred_check_setgid, cred, gid); + MAC_CHECK_NOSLEEP(cred_check_setgid, cred, gid); MAC_CHECK_PROBE2(cred_check_setgid, error, cred, gid); return (error); @@ -257,7 +257,7 @@ mac_cred_check_setegid(struct ucred *cred, gid_t egid) { int error; - MAC_CHECK(cred_check_setegid, cred, egid); + MAC_CHECK_NOSLEEP(cred_check_setegid, cred, egid); MAC_CHECK_PROBE2(cred_check_setegid, error, cred, egid); return (error); @@ -271,7 +271,7 @@ mac_cred_check_setgroups(struct ucred *cred, int ngroups, gid_t *gidset) { int error; - MAC_CHECK(cred_check_setgroups, cred, ngroups, gidset); + MAC_CHECK_NOSLEEP(cred_check_setgroups, cred, ngroups, gidset); MAC_CHECK_PROBE3(cred_check_setgroups, error, cred, ngroups, gidset); return (error); @@ -285,7 +285,7 @@ mac_cred_check_setreuid(struct ucred *cred, uid_t ruid, uid_t euid) { int error; - MAC_CHECK(cred_check_setreuid, cred, ruid, euid); + MAC_CHECK_NOSLEEP(cred_check_setreuid, cred, ruid, euid); MAC_CHECK_PROBE3(cred_check_setreuid, error, cred, ruid, euid); return (error); @@ -299,7 +299,7 @@ mac_cred_check_setregid(struct ucred *cred, gid_t rgid, gid_t egid) { int error; - MAC_CHECK(cred_check_setregid, cred, rgid, egid); + MAC_CHECK_NOSLEEP(cred_check_setregid, cred, rgid, egid); MAC_CHECK_PROBE3(cred_check_setregid, error, cred, rgid, egid); return (error); @@ -314,7 +314,7 @@ mac_cred_check_setresuid(struct ucred *cred, uid_t ruid, uid_t euid, { int error; - MAC_CHECK(cred_check_setresuid, cred, ruid, euid, suid); + MAC_CHECK_NOSLEEP(cred_check_setresuid, cred, ruid, euid, suid); MAC_CHECK_PROBE4(cred_check_setresuid, error, cred, ruid, euid, suid); @@ -330,7 +330,7 @@ mac_cred_check_setresgid(struct ucred *cred, gid_t rgid, gid_t egid, { int error; - MAC_CHECK(cred_check_setresgid, cred, rgid, egid, sgid); + MAC_CHECK_NOSLEEP(cred_check_setresgid, cred, rgid, egid, sgid); MAC_CHECK_PROBE4(cred_check_setresgid, error, cred, rgid, egid, sgid); @@ -345,7 +345,7 @@ mac_cred_check_visible(struct ucred *cr1, struct ucred *cr2) { int error; - MAC_CHECK(cred_check_visible, cr1, cr2); + MAC_CHECK_NOSLEEP(cred_check_visible, cr1, cr2); MAC_CHECK_PROBE2(cred_check_visible, error, cr1, cr2); return (error); diff --git a/sys/security/mac/mac_framework.c b/sys/security/mac/mac_framework.c index f434df8..1806e4a 100644 --- a/sys/security/mac/mac_framework.c +++ b/sys/security/mac/mac_framework.c @@ -76,10 +76,11 @@ __FBSDID("$FreeBSD$"); #include <sys/condvar.h> #include <sys/kernel.h> #include <sys/lock.h> -#include <sys/mutex.h> #include <sys/mac.h> #include <sys/module.h> +#include <sys/rwlock.h> #include <sys/sdt.h> +#include <sys/sx.h> #include <sys/systm.h> #include <sys/sysctl.h> @@ -154,164 +155,125 @@ SYSCTL_QUAD(_security_mac, OID_AUTO, labeled, CTLFLAG_RD, &mac_labeled, 0, MALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage"); /* - * mac_static_policy_list holds a list of policy modules that are not loaded - * while the system is "live", and cannot be unloaded. These policies can be - * invoked without holding the busy count. + * MAC policy modules are placed in one of two lists: mac_static_policy_list, + * for policies that are loaded early and cannot be unloaded, and + * mac_policy_list, which holds policies either loaded later in the boot + * cycle or that may be unloaded. The static policy list does not require + * locks to iterate over, but the dynamic list requires synchronization. + * Support for dynamic policy loading can be compiled out using the + * MAC_STATIC kernel option. * - * mac_policy_list stores the list of dynamic policies. A busy count is - * maintained for the list, stored in mac_policy_busy. The busy count is - * protected by mac_policy_mtx; the list may be modified only while the busy - * count is 0, requiring that the lock be held to prevent new references to - * the list from being acquired. For almost all operations, incrementing the - * busy count is sufficient to guarantee consistency, as the list cannot be - * modified while the busy count is elevated. For a few special operations - * involving a change to the list of active policies, the mtx itself must be - * held. A condition variable, mac_policy_cv, is used to signal potential - * exclusive consumers that they should try to acquire the lock if a first - * attempt at exclusive access fails. - * - * This design intentionally avoids fairness, and may starve attempts to - * acquire an exclusive lock on a busy system. This is required because we - * do not ever want acquiring a read reference to perform an unbounded length - * sleep. Read references are acquired in ithreads, network isrs, etc, and - * any unbounded blocking could lead quickly to deadlock. - * - * Another reason for never blocking on read references is that the MAC - * Framework may recurse: if a policy calls a VOP, for example, this might - * lead to vnode life cycle operations (such as init/destroy). - * - * If the kernel option MAC_STATIC has been compiled in, all locking becomes - * a no-op, and the global list of policies is not allowed to change after - * early boot. - * - * XXXRW: Currently, we signal mac_policy_cv every time the framework becomes - * unbusy and there is a thread waiting to enter it exclusively. Since it - * may take some time before the thread runs, we may issue a lot of signals. - * We should instead keep track of the fact that we've signalled, taking into - * account that the framework may be busy again by the time the thread runs, - * requiring us to re-signal. + * The dynamic policy list is protected by two locks: modifying the list + * requires both locks to be held exclusively. One of the locks, + * mac_policy_rw, is acquired over policy entry points that will never sleep; + * the other, mac_policy_sx, is acquire over policy entry points that may + * sleep. The former category will be used when kernel locks may be held + * over calls to the MAC Framework, during network processing in ithreads, + * etc. The latter will tend to involve potentially blocking memory + * allocations, extended attribute I/O, etc. */ #ifndef MAC_STATIC -static struct mtx mac_policy_mtx; -static struct cv mac_policy_cv; -static int mac_policy_count; -static int mac_policy_wait; +static struct rwlock mac_policy_rw; /* Non-sleeping entry points. */ +static struct sx mac_policy_sx; /* Sleeping entry points. */ #endif + struct mac_policy_list_head mac_policy_list; struct mac_policy_list_head mac_static_policy_list; -/* - * We manually invoke WITNESS_WARN() to allow Witness to generate warnings - * even if we don't end up ever triggering the wait at run-time. The - * consumer of the exclusive interface must not hold any locks (other than - * potentially Giant) since we may sleep for long (potentially indefinite) - * periods of time waiting for the framework to become quiescent so that a - * policy list change may be made. - */ +static void mac_policy_xlock(void); +static void mac_policy_xlock_assert(void); +static void mac_policy_xunlock(void); + void -mac_policy_grab_exclusive(void) +mac_policy_slock_nosleep(void) { #ifndef MAC_STATIC if (!mac_late) return; - WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, - "mac_policy_grab_exclusive() at %s:%d", __FILE__, __LINE__); - mtx_lock(&mac_policy_mtx); - while (mac_policy_count != 0) { - mac_policy_wait++; - cv_wait(&mac_policy_cv, &mac_policy_mtx); - mac_policy_wait--; - } + rw_rlock(&mac_policy_rw); #endif } void -mac_policy_assert_exclusive(void) +mac_policy_slock_sleep(void) { + WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, + "mac_policy_slock_sleep"); + #ifndef MAC_STATIC if (!mac_late) return; - mtx_assert(&mac_policy_mtx, MA_OWNED); - KASSERT(mac_policy_count == 0, - ("mac_policy_assert_exclusive(): not exclusive")); + sx_slock(&mac_policy_sx); #endif } void -mac_policy_release_exclusive(void) +mac_policy_sunlock_nosleep(void) { -#ifndef MAC_STATIC - int dowakeup; +#ifndef MAC_STATIC if (!mac_late) return; - KASSERT(mac_policy_count == 0, - ("mac_policy_release_exclusive(): not exclusive")); - dowakeup = (mac_policy_wait != 0); - mtx_unlock(&mac_policy_mtx); - if (dowakeup) - cv_signal(&mac_policy_cv); + rw_runlock(&mac_policy_rw); #endif } void -mac_policy_list_busy(void) +mac_policy_sunlock_sleep(void) { #ifndef MAC_STATIC if (!mac_late) return; - mtx_lock(&mac_policy_mtx); - mac_policy_count++; - mtx_unlock(&mac_policy_mtx); + sx_sunlock(&mac_policy_sx); #endif } -int -mac_policy_list_conditional_busy(void) +static void +mac_policy_xlock(void) { -#ifndef MAC_STATIC - int ret; + WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, + "mac_policy_xlock()"); + +#ifndef MAC_STATIC if (!mac_late) - return (1); - - mtx_lock(&mac_policy_mtx); - if (!LIST_EMPTY(&mac_policy_list)) { - mac_policy_count++; - ret = 1; - } else - ret = 0; - mtx_unlock(&mac_policy_mtx); - return (ret); -#else - return (1); + return; + + sx_xlock(&mac_policy_sx); + rw_wlock(&mac_policy_rw); #endif } -void -mac_policy_list_unbusy(void) +static void +mac_policy_xunlock(void) { -#ifndef MAC_STATIC - int dowakeup; +#ifndef MAC_STATIC if (!mac_late) return; - mtx_lock(&mac_policy_mtx); - mac_policy_count--; - KASSERT(mac_policy_count >= 0, ("MAC_POLICY_LIST_LOCK")); - dowakeup = (mac_policy_count == 0 && mac_policy_wait != 0); - mtx_unlock(&mac_policy_mtx); + rw_wunlock(&mac_policy_rw); + sx_xunlock(&mac_policy_sx); +#endif +} + +static void +mac_policy_xlock_assert(void) +{ - if (dowakeup) - cv_signal(&mac_policy_cv); +#ifndef MAC_STATIC + if (!mac_late) + return; + + rw_assert(&mac_policy_rw, RA_WLOCKED); + sx_assert(&mac_policy_sx, SA_XLOCKED); #endif } @@ -327,8 +289,8 @@ mac_init(void) mac_labelzone_init(); #ifndef MAC_STATIC - mtx_init(&mac_policy_mtx, "mac_policy_mtx", NULL, MTX_DEF); - cv_init(&mac_policy_cv, "mac_policy_cv"); + rw_init(&mac_policy_rw, "mac_policy_rw"); + sx_init(&mac_policy_sx, "mac_policy_sx"); #endif } @@ -393,7 +355,7 @@ mac_policy_updateflags(void) { struct mac_policy_conf *mpc; - mac_policy_assert_exclusive(); + mac_policy_xlock_assert(); mac_labeled = 0; LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) @@ -414,7 +376,7 @@ mac_policy_register(struct mac_policy_conf *mpc) * We don't technically need exclusive access while !mac_late, but * hold it for assertion consistency. */ - mac_policy_grab_exclusive(); + mac_policy_xlock(); /* * If the module can potentially be unloaded, or we're loading late, @@ -479,7 +441,7 @@ mac_policy_register(struct mac_policy_conf *mpc) mpc->mpc_name); out: - mac_policy_release_exclusive(); + mac_policy_xunlock(); return (error); } @@ -491,9 +453,9 @@ mac_policy_unregister(struct mac_policy_conf *mpc) * If we fail the load, we may get a request to unload. Check to see * if we did the run-time registration, and if not, silently succeed. */ - mac_policy_grab_exclusive(); + mac_policy_xlock(); if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) == 0) { - mac_policy_release_exclusive(); + mac_policy_xunlock(); return (0); } #if 0 @@ -501,7 +463,7 @@ mac_policy_unregister(struct mac_policy_conf *mpc) * Don't allow unloading modules with private data. */ if (mpc->mpc_field_off != NULL) { - MAC_POLICY_LIST_UNLOCK(); + mac_policy_xunlock(); return (EBUSY); } #endif @@ -510,7 +472,7 @@ mac_policy_unregister(struct mac_policy_conf *mpc) * its own definition. */ if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) { - mac_policy_release_exclusive(); + mac_policy_xunlock(); return (EBUSY); } if (mpc->mpc_ops->mpo_destroy != NULL) @@ -519,8 +481,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_release_exclusive(); + mac_policy_xunlock(); SDT_PROBE(mac, kernel, policy, unregister, mpc, 0, 0, 0, 0); printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname, diff --git a/sys/security/mac/mac_inet.c b/sys/security/mac/mac_inet.c index b62938b..df21a16 100644 --- a/sys/security/mac/mac_inet.c +++ b/sys/security/mac/mac_inet.c @@ -84,9 +84,12 @@ mac_inpcb_label_alloc(int flag) label = mac_labelzone_alloc(flag); if (label == NULL) return (NULL); - MAC_CHECK(inpcb_init_label, label, flag); + if (flag & M_WAITOK) + MAC_CHECK(inpcb_init_label, label, flag); + else + MAC_CHECK_NOSLEEP(inpcb_init_label, label, flag); if (error) { - MAC_PERFORM(inpcb_destroy_label, label); + MAC_PERFORM_NOSLEEP(inpcb_destroy_label, label); mac_labelzone_free(label); return (NULL); } @@ -116,9 +119,12 @@ mac_ipq_label_alloc(int flag) if (label == NULL) return (NULL); - MAC_CHECK(ipq_init_label, label, flag); + if (flag & M_WAITOK) + MAC_CHECK(ipq_init_label, label, flag); + else + MAC_CHECK_NOSLEEP(ipq_init_label, label, flag); if (error) { - MAC_PERFORM(ipq_destroy_label, label); + MAC_PERFORM_NOSLEEP(ipq_destroy_label, label); mac_labelzone_free(label); return (NULL); } @@ -142,7 +148,7 @@ static void mac_inpcb_label_free(struct label *label) { - MAC_PERFORM(inpcb_destroy_label, label); + MAC_PERFORM_NOSLEEP(inpcb_destroy_label, label); mac_labelzone_free(label); } @@ -160,7 +166,7 @@ static void mac_ipq_label_free(struct label *label) { - MAC_PERFORM(ipq_destroy_label, label); + MAC_PERFORM_NOSLEEP(ipq_destroy_label, label); mac_labelzone_free(label); } @@ -178,7 +184,8 @@ void mac_inpcb_create(struct socket *so, struct inpcb *inp) { - MAC_PERFORM(inpcb_create, so, so->so_label, inp, inp->inp_label); + MAC_PERFORM_NOSLEEP(inpcb_create, so, so->so_label, inp, + inp->inp_label); } void @@ -188,7 +195,7 @@ mac_ipq_reassemble(struct ipq *q, struct mbuf *m) label = mac_mbuf_to_label(m); - MAC_PERFORM(ipq_reassemble, q, q->ipq_label, m, label); + MAC_PERFORM_NOSLEEP(ipq_reassemble, q, q->ipq_label, m, label); } void @@ -199,7 +206,7 @@ mac_netinet_fragment(struct mbuf *m, struct mbuf *frag) mlabel = mac_mbuf_to_label(m); fraglabel = mac_mbuf_to_label(frag); - MAC_PERFORM(netinet_fragment, m, mlabel, frag, fraglabel); + MAC_PERFORM_NOSLEEP(netinet_fragment, m, mlabel, frag, fraglabel); } void @@ -209,7 +216,7 @@ mac_ipq_create(struct mbuf *m, struct ipq *q) label = mac_mbuf_to_label(m); - MAC_PERFORM(ipq_create, m, label, q, q->ipq_label); + MAC_PERFORM_NOSLEEP(ipq_create, m, label, q, q->ipq_label); } void @@ -220,7 +227,8 @@ mac_inpcb_create_mbuf(struct inpcb *inp, struct mbuf *m) INP_LOCK_ASSERT(inp); mlabel = mac_mbuf_to_label(m); - MAC_PERFORM(inpcb_create_mbuf, inp, inp->inp_label, m, mlabel); + MAC_PERFORM_NOSLEEP(inpcb_create_mbuf, inp, inp->inp_label, m, + mlabel); } int @@ -232,7 +240,7 @@ mac_ipq_match(struct mbuf *m, struct ipq *q) label = mac_mbuf_to_label(m); result = 1; - MAC_BOOLEAN(ipq_match, &&, m, label, q, q->ipq_label); + MAC_BOOLEAN_NOSLEEP(ipq_match, &&, m, label, q, q->ipq_label); return (result); } @@ -245,7 +253,7 @@ mac_netinet_arp_send(struct ifnet *ifp, struct mbuf *m) mlabel = mac_mbuf_to_label(m); MAC_IFNET_LOCK(ifp); - MAC_PERFORM(netinet_arp_send, ifp, ifp->if_label, m, mlabel); + MAC_PERFORM_NOSLEEP(netinet_arp_send, ifp, ifp->if_label, m, mlabel); MAC_IFNET_UNLOCK(ifp); } @@ -257,7 +265,7 @@ mac_netinet_icmp_reply(struct mbuf *mrecv, struct mbuf *msend) mrecvlabel = mac_mbuf_to_label(mrecv); msendlabel = mac_mbuf_to_label(msend); - MAC_PERFORM(netinet_icmp_reply, mrecv, mrecvlabel, msend, + MAC_PERFORM_NOSLEEP(netinet_icmp_reply, mrecv, mrecvlabel, msend, msendlabel); } @@ -268,7 +276,7 @@ mac_netinet_icmp_replyinplace(struct mbuf *m) label = mac_mbuf_to_label(m); - MAC_PERFORM(netinet_icmp_replyinplace, m, label); + MAC_PERFORM_NOSLEEP(netinet_icmp_replyinplace, m, label); } void @@ -279,7 +287,8 @@ mac_netinet_igmp_send(struct ifnet *ifp, struct mbuf *m) mlabel = mac_mbuf_to_label(m); MAC_IFNET_LOCK(ifp); - MAC_PERFORM(netinet_igmp_send, ifp, ifp->if_label, m, mlabel); + MAC_PERFORM_NOSLEEP(netinet_igmp_send, ifp, ifp->if_label, m, + mlabel); MAC_IFNET_UNLOCK(ifp); } @@ -290,7 +299,7 @@ mac_netinet_tcp_reply(struct mbuf *m) label = mac_mbuf_to_label(m); - MAC_PERFORM(netinet_tcp_reply, m, label); + MAC_PERFORM_NOSLEEP(netinet_tcp_reply, m, label); } void @@ -300,7 +309,7 @@ mac_ipq_update(struct mbuf *m, struct ipq *q) label = mac_mbuf_to_label(m); - MAC_PERFORM(ipq_update, m, label, q, q->ipq_label); + MAC_PERFORM_NOSLEEP(ipq_update, m, label, q, q->ipq_label); } MAC_CHECK_PROBE_DEFINE2(inpcb_check_deliver, "struct inpcb *", @@ -316,7 +325,8 @@ mac_inpcb_check_deliver(struct inpcb *inp, struct mbuf *m) label = mac_mbuf_to_label(m); - MAC_CHECK(inpcb_check_deliver, inp, inp->inp_label, m, label); + MAC_CHECK_NOSLEEP(inpcb_check_deliver, inp, inp->inp_label, m, + label); MAC_CHECK_PROBE2(inpcb_check_deliver, error, inp, m); return (error); @@ -332,7 +342,7 @@ mac_inpcb_check_visible(struct ucred *cred, struct inpcb *inp) INP_LOCK_ASSERT(inp); - MAC_CHECK(inpcb_check_visible, cred, inp, inp->inp_label); + MAC_CHECK_NOSLEEP(inpcb_check_visible, cred, inp, inp->inp_label); MAC_CHECK_PROBE2(inpcb_check_visible, error, cred, inp); return (error); @@ -344,7 +354,9 @@ mac_inpcb_sosetlabel(struct socket *so, struct inpcb *inp) INP_WLOCK_ASSERT(inp); SOCK_LOCK_ASSERT(so); - MAC_PERFORM(inpcb_sosetlabel, so, so->so_label, inp, inp->inp_label); + + MAC_PERFORM_NOSLEEP(inpcb_sosetlabel, so, so->so_label, inp, + inp->inp_label); } void @@ -358,7 +370,7 @@ mac_netinet_firewall_reply(struct mbuf *mrecv, struct mbuf *msend) mrecvlabel = mac_mbuf_to_label(mrecv); msendlabel = mac_mbuf_to_label(msend); - MAC_PERFORM(netinet_firewall_reply, mrecv, mrecvlabel, msend, + MAC_PERFORM_NOSLEEP(netinet_firewall_reply, mrecv, mrecvlabel, msend, msendlabel); } @@ -368,8 +380,10 @@ mac_netinet_firewall_send(struct mbuf *m) struct label *label; M_ASSERTPKTHDR(m); + label = mac_mbuf_to_label(m); - MAC_PERFORM(netinet_firewall_send, m, label); + + MAC_PERFORM_NOSLEEP(netinet_firewall_send, m, label); } /* @@ -386,7 +400,7 @@ mac_syncache_destroy(struct label **label) { if (*label != NULL) { - MAC_PERFORM(syncache_destroy_label, *label); + MAC_PERFORM_NOSLEEP(syncache_destroy_label, *label); mac_labelzone_free(*label); *label = NULL; } @@ -408,9 +422,9 @@ mac_syncache_init(struct label **label) * MAC_PERFORM so we can propagate allocation failures back * to the syncache code. */ - MAC_CHECK(syncache_init_label, *label, M_NOWAIT); + MAC_CHECK_NOSLEEP(syncache_init_label, *label, M_NOWAIT); if (error) { - MAC_PERFORM(syncache_destroy_label, *label); + MAC_PERFORM_NOSLEEP(syncache_destroy_label, *label); mac_labelzone_free(*label); } return (error); @@ -424,7 +438,8 @@ mac_syncache_create(struct label *label, struct inpcb *inp) { INP_WLOCK_ASSERT(inp); - MAC_PERFORM(syncache_create, label, inp); + + MAC_PERFORM_NOSLEEP(syncache_create, label, inp); } void @@ -433,6 +448,8 @@ mac_syncache_create_mbuf(struct label *sc_label, struct mbuf *m) struct label *mlabel; M_ASSERTPKTHDR(m); + mlabel = mac_mbuf_to_label(m); - MAC_PERFORM(syncache_create_mbuf, sc_label, m, mlabel); + + MAC_PERFORM_NOSLEEP(syncache_create_mbuf, sc_label, m, mlabel); } diff --git a/sys/security/mac/mac_inet6.c b/sys/security/mac/mac_inet6.c index 9201b36..f804fe3 100644 --- a/sys/security/mac/mac_inet6.c +++ b/sys/security/mac/mac_inet6.c @@ -1,9 +1,12 @@ /*- - * Copyright (c) 2007-2008 Robert N. M. Watson + * Copyright (c) 2007-2009 Robert N. M. Watson * All rights reserved. * * This software was developed by Robert Watson for the TrustedBSD Project. * + * This software was developed at the University of Cambridge Computer + * Laboratory with support from a grant from Google, Inc. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -67,9 +70,12 @@ mac_ip6q_label_alloc(int flag) if (label == NULL) return (NULL); - MAC_CHECK(ip6q_init_label, label, flag); + if (flag & M_WAITOK) + MAC_CHECK(ip6q_init_label, label, flag); + else + MAC_CHECK_NOSLEEP(ip6q_init_label, label, flag); if (error) { - MAC_PERFORM(ip6q_destroy_label, label); + MAC_PERFORM_NOSLEEP(ip6q_destroy_label, label); mac_labelzone_free(label); return (NULL); } @@ -93,7 +99,7 @@ static void mac_ip6q_label_free(struct label *label) { - MAC_PERFORM(ip6q_destroy_label, label); + MAC_PERFORM_NOSLEEP(ip6q_destroy_label, label); mac_labelzone_free(label); } @@ -114,7 +120,7 @@ mac_ip6q_reassemble(struct ip6q *q6, struct mbuf *m) label = mac_mbuf_to_label(m); - MAC_PERFORM(ip6q_reassemble, q6, q6->ip6q_label, m, label); + MAC_PERFORM_NOSLEEP(ip6q_reassemble, q6, q6->ip6q_label, m, label); } void @@ -124,7 +130,7 @@ mac_ip6q_create(struct mbuf *m, struct ip6q *q6) label = mac_mbuf_to_label(m); - MAC_PERFORM(ip6q_create, m, label, q6, q6->ip6q_label); + MAC_PERFORM_NOSLEEP(ip6q_create, m, label, q6, q6->ip6q_label); } int @@ -136,7 +142,7 @@ mac_ip6q_match(struct mbuf *m, struct ip6q *q6) label = mac_mbuf_to_label(m); result = 1; - MAC_BOOLEAN(ip6q_match, &&, m, label, q6, q6->ip6q_label); + MAC_BOOLEAN_NOSLEEP(ip6q_match, &&, m, label, q6, q6->ip6q_label); return (result); } @@ -148,7 +154,7 @@ mac_ip6q_update(struct mbuf *m, struct ip6q *q6) label = mac_mbuf_to_label(m); - MAC_PERFORM(ip6q_update, m, label, q6, q6->ip6q_label); + MAC_PERFORM_NOSLEEP(ip6q_update, m, label, q6, q6->ip6q_label); } void @@ -158,5 +164,6 @@ mac_netinet6_nd6_send(struct ifnet *ifp, struct mbuf *m) mlabel = mac_mbuf_to_label(m); - MAC_PERFORM(netinet6_nd6_send, ifp, ifp->if_label, m, mlabel); + MAC_PERFORM_NOSLEEP(netinet6_nd6_send, ifp, ifp->if_label, m, + mlabel); } diff --git a/sys/security/mac/mac_internal.h b/sys/security/mac/mac_internal.h index 34336fc..280c8b8 100644 --- a/sys/security/mac/mac_internal.h +++ b/sys/security/mac/mac_internal.h @@ -194,12 +194,10 @@ extern struct mtx mac_ifnet_mtx; */ int mac_error_select(int error1, int error2); -void mac_policy_grab_exclusive(void); -void mac_policy_assert_exclusive(void); -void mac_policy_release_exclusive(void); -void mac_policy_list_busy(void); -int mac_policy_list_conditional_busy(void); -void mac_policy_list_unbusy(void); +void mac_policy_slock_nosleep(void); +void mac_policy_slock_sleep(void); +void mac_policy_sunlock_nosleep(void); +void mac_policy_sunlock_sleep(void); struct label *mac_labelzone_alloc(int flags); void mac_labelzone_free(struct label *label); @@ -255,13 +253,16 @@ int vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred); /* + * MAC Framework composition macros invoke all registered MAC policies for a + * specific entry point. They come in two forms: one which permits policies + * to sleep/block, and another that does not. + * * MAC_CHECK performs the designated check by walking the policy module list * and checking with each as to how it feels about the request. Note that it * returns its value via 'error' in the scope of the caller. */ #define MAC_CHECK(check, args...) do { \ struct mac_policy_conf *mpc; \ - int entrycount; \ \ error = 0; \ LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { \ @@ -270,14 +271,37 @@ int vn_setlabel(struct vnode *vp, struct label *intlabel, mpc->mpc_ops->mpo_ ## check (args), \ error); \ } \ - if ((entrycount = mac_policy_list_conditional_busy()) != 0) { \ + if (!LIST_EMPTY(&mac_policy_list)) { \ + mac_policy_slock_sleep(); \ + LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ + if (mpc->mpc_ops->mpo_ ## check != NULL) \ + error = mac_error_select( \ + mpc->mpc_ops->mpo_ ## check (args), \ + error); \ + } \ + mac_policy_sunlock_sleep(); \ + } \ +} while (0) + +#define MAC_CHECK_NOSLEEP(check, args...) do { \ + struct mac_policy_conf *mpc; \ + \ + error = 0; \ + LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { \ + if (mpc->mpc_ops->mpo_ ## check != NULL) \ + error = mac_error_select( \ + mpc->mpc_ops->mpo_ ## check (args), \ + error); \ + } \ + if (!LIST_EMPTY(&mac_policy_list)) { \ + mac_policy_slock_nosleep(); \ LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ if (mpc->mpc_ops->mpo_ ## check != NULL) \ error = mac_error_select( \ mpc->mpc_ops->mpo_ ## check (args), \ error); \ } \ - mac_policy_list_unbusy(); \ + mac_policy_sunlock_nosleep(); \ } \ } while (0) @@ -288,9 +312,8 @@ int vn_setlabel(struct vnode *vp, struct label *intlabel, * EPERM. Note that it returns its value via 'error' in the scope of the * caller. */ -#define MAC_GRANT(check, args...) do { \ +#define MAC_GRANT_NOSLEEP(check, args...) do { \ struct mac_policy_conf *mpc; \ - int entrycount; \ \ error = EPERM; \ LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { \ @@ -299,7 +322,8 @@ int vn_setlabel(struct vnode *vp, struct label *intlabel, error = 0; \ } \ } \ - if ((entrycount = mac_policy_list_conditional_busy()) != 0) { \ + if (!LIST_EMPTY(&mac_policy_list)) { \ + mac_policy_slock_nosleep(); \ LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ if (mpc->mpc_ops->mpo_ ## check != NULL) { \ if (mpc->mpc_ops->mpo_ ## check (args) \ @@ -307,7 +331,7 @@ int vn_setlabel(struct vnode *vp, struct label *intlabel, error = 0; \ } \ } \ - mac_policy_list_unbusy(); \ + mac_policy_sunlock_nosleep(); \ } \ } while (0) @@ -320,21 +344,41 @@ int vn_setlabel(struct vnode *vp, struct label *intlabel, */ #define MAC_BOOLEAN(operation, composition, args...) do { \ struct mac_policy_conf *mpc; \ - int entrycount; \ \ LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { \ if (mpc->mpc_ops->mpo_ ## operation != NULL) \ result = result composition \ mpc->mpc_ops->mpo_ ## operation (args); \ } \ - if ((entrycount = mac_policy_list_conditional_busy()) != 0) { \ + if (!LIST_EMPTY(&mac_policy_list)) { \ + mac_policy_slock_sleep(); \ + LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ + if (mpc->mpc_ops->mpo_ ## operation != NULL) \ + result = result composition \ + mpc->mpc_ops->mpo_ ## operation \ + (args); \ + } \ + mac_policy_sunlock_sleep(); \ + } \ +} while (0) + +#define MAC_BOOLEAN_NOSLEEP(operation, composition, args...) do { \ + struct mac_policy_conf *mpc; \ + \ + LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { \ + if (mpc->mpc_ops->mpo_ ## operation != NULL) \ + result = result composition \ + mpc->mpc_ops->mpo_ ## operation (args); \ + } \ + if (!LIST_EMPTY(&mac_policy_list)) { \ + mac_policy_slock_nosleep(); \ LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ if (mpc->mpc_ops->mpo_ ## operation != NULL) \ result = result composition \ mpc->mpc_ops->mpo_ ## operation \ (args); \ } \ - mac_policy_list_unbusy(); \ + mac_policy_sunlock_nosleep(); \ } \ } while (0) @@ -425,18 +469,35 @@ int vn_setlabel(struct vnode *vp, struct label *intlabel, */ #define MAC_PERFORM(operation, args...) do { \ struct mac_policy_conf *mpc; \ - int entrycount; \ \ LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { \ if (mpc->mpc_ops->mpo_ ## operation != NULL) \ mpc->mpc_ops->mpo_ ## operation (args); \ } \ - if ((entrycount = mac_policy_list_conditional_busy()) != 0) { \ + if (!LIST_EMPTY(&mac_policy_list)) { \ + mac_policy_slock_sleep(); \ + LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ + if (mpc->mpc_ops->mpo_ ## operation != NULL) \ + mpc->mpc_ops->mpo_ ## operation (args); \ + } \ + mac_policy_sunlock_sleep(); \ + } \ +} while (0) + +#define MAC_PERFORM_NOSLEEP(operation, args...) do { \ + struct mac_policy_conf *mpc; \ + \ + LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { \ + if (mpc->mpc_ops->mpo_ ## operation != NULL) \ + mpc->mpc_ops->mpo_ ## operation (args); \ + } \ + if (!LIST_EMPTY(&mac_policy_list)) { \ + mac_policy_slock_nosleep(); \ LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ if (mpc->mpc_ops->mpo_ ## operation != NULL) \ mpc->mpc_ops->mpo_ ## operation (args); \ } \ - mac_policy_list_unbusy(); \ + mac_policy_sunlock_nosleep(); \ } \ } while (0) diff --git a/sys/security/mac/mac_net.c b/sys/security/mac/mac_net.c index 4fccbd7..697d02a 100644 --- a/sys/security/mac/mac_net.c +++ b/sys/security/mac/mac_net.c @@ -153,9 +153,12 @@ mac_mbuf_tag_init(struct m_tag *tag, int flag) label = (struct label *) (tag + 1); mac_init_label(label); - MAC_CHECK(mbuf_init_label, label, flag); + if (flag & M_WAITOK) + MAC_CHECK(mbuf_init_label, label, flag); + else + MAC_CHECK_NOSLEEP(mbuf_init_label, label, flag); if (error) { - MAC_PERFORM(mbuf_destroy_label, label); + MAC_PERFORM_NOSLEEP(mbuf_destroy_label, label); mac_destroy_label(label); } return (error); @@ -188,7 +191,7 @@ static void mac_bpfdesc_label_free(struct label *label) { - MAC_PERFORM(bpfdesc_destroy_label, label); + MAC_PERFORM_NOSLEEP(bpfdesc_destroy_label, label); mac_labelzone_free(label); } @@ -206,7 +209,7 @@ static void mac_ifnet_label_free(struct label *label) { - MAC_PERFORM(ifnet_destroy_label, label); + MAC_PERFORM_NOSLEEP(ifnet_destroy_label, label); mac_labelzone_free(label); } @@ -227,7 +230,7 @@ mac_mbuf_tag_destroy(struct m_tag *tag) label = (struct label *)(tag+1); - MAC_PERFORM(mbuf_destroy_label, label); + MAC_PERFORM_NOSLEEP(mbuf_destroy_label, label); mac_destroy_label(label); } @@ -247,7 +250,7 @@ mac_mbuf_tag_copy(struct m_tag *src, struct m_tag *dest) * mac_mbuf_tag_init() is called on the target tag in m_tag_copy(), * so we don't need to call it here. */ - MAC_PERFORM(mbuf_copy_label, src_label, dest_label); + MAC_PERFORM_NOSLEEP(mbuf_copy_label, src_label, dest_label); } void @@ -258,14 +261,14 @@ mac_mbuf_copy(struct mbuf *m_from, struct mbuf *m_to) src_label = mac_mbuf_to_label(m_from); dest_label = mac_mbuf_to_label(m_to); - MAC_PERFORM(mbuf_copy_label, src_label, dest_label); + MAC_PERFORM_NOSLEEP(mbuf_copy_label, src_label, dest_label); } static void mac_ifnet_copy_label(struct label *src, struct label *dest) { - MAC_PERFORM(ifnet_copy_label, src, dest); + MAC_PERFORM_NOSLEEP(ifnet_copy_label, src, dest); } static int @@ -294,7 +297,7 @@ mac_ifnet_create(struct ifnet *ifp) { MAC_IFNET_LOCK(ifp); - MAC_PERFORM(ifnet_create, ifp, ifp->if_label); + MAC_PERFORM_NOSLEEP(ifnet_create, ifp, ifp->if_label); MAC_IFNET_UNLOCK(ifp); } @@ -302,7 +305,7 @@ void mac_bpfdesc_create(struct ucred *cred, struct bpf_d *d) { - MAC_PERFORM(bpfdesc_create, cred, d, d->bd_label); + MAC_PERFORM_NOSLEEP(bpfdesc_create, cred, d, d->bd_label); } void @@ -314,7 +317,7 @@ mac_bpfdesc_create_mbuf(struct bpf_d *d, struct mbuf *m) label = mac_mbuf_to_label(m); - MAC_PERFORM(bpfdesc_create_mbuf, d, d->bd_label, m, label); + MAC_PERFORM_NOSLEEP(bpfdesc_create_mbuf, d, d->bd_label, m, label); } void @@ -325,7 +328,7 @@ mac_ifnet_create_mbuf(struct ifnet *ifp, struct mbuf *m) label = mac_mbuf_to_label(m); MAC_IFNET_LOCK(ifp); - MAC_PERFORM(ifnet_create_mbuf, ifp, ifp->if_label, m, label); + MAC_PERFORM_NOSLEEP(ifnet_create_mbuf, ifp, ifp->if_label, m, label); MAC_IFNET_UNLOCK(ifp); } @@ -340,7 +343,8 @@ mac_bpfdesc_check_receive(struct bpf_d *d, struct ifnet *ifp) BPFD_LOCK_ASSERT(d); MAC_IFNET_LOCK(ifp); - MAC_CHECK(bpfdesc_check_receive, d, d->bd_label, ifp, ifp->if_label); + MAC_CHECK_NOSLEEP(bpfdesc_check_receive, d, d->bd_label, ifp, + ifp->if_label); MAC_CHECK_PROBE2(bpfdesc_check_receive, error, d, ifp); MAC_IFNET_UNLOCK(ifp); @@ -361,7 +365,8 @@ mac_ifnet_check_transmit(struct ifnet *ifp, struct mbuf *m) label = mac_mbuf_to_label(m); MAC_IFNET_LOCK(ifp); - MAC_CHECK(ifnet_check_transmit, ifp, ifp->if_label, m, label); + MAC_CHECK_NOSLEEP(ifnet_check_transmit, ifp, ifp->if_label, m, + label); MAC_CHECK_PROBE2(ifnet_check_transmit, error, ifp, m); MAC_IFNET_UNLOCK(ifp); @@ -458,14 +463,16 @@ mac_ifnet_ioctl_set(struct ucred *cred, struct ifreq *ifr, struct ifnet *ifp) } MAC_IFNET_LOCK(ifp); - MAC_CHECK(ifnet_check_relabel, cred, ifp, ifp->if_label, intlabel); + MAC_CHECK_NOSLEEP(ifnet_check_relabel, cred, ifp, ifp->if_label, + intlabel); if (error) { MAC_IFNET_UNLOCK(ifp); mac_ifnet_label_free(intlabel); return (error); } - MAC_PERFORM(ifnet_relabel, cred, ifp, ifp->if_label, intlabel); + MAC_PERFORM_NOSLEEP(ifnet_relabel, cred, ifp, ifp->if_label, + intlabel); MAC_IFNET_UNLOCK(ifp); mac_ifnet_label_free(intlabel); diff --git a/sys/security/mac/mac_pipe.c b/sys/security/mac/mac_pipe.c index 921fd20..160a944 100644 --- a/sys/security/mac/mac_pipe.c +++ b/sys/security/mac/mac_pipe.c @@ -84,7 +84,7 @@ void mac_pipe_label_free(struct label *label) { - MAC_PERFORM(pipe_destroy_label, label); + MAC_PERFORM_NOSLEEP(pipe_destroy_label, label); mac_labelzone_free(label); } @@ -102,7 +102,7 @@ void mac_pipe_copy_label(struct label *src, struct label *dest) { - MAC_PERFORM(pipe_copy_label, src, dest); + MAC_PERFORM_NOSLEEP(pipe_copy_label, src, dest); } int @@ -130,7 +130,7 @@ void mac_pipe_create(struct ucred *cred, struct pipepair *pp) { - MAC_PERFORM(pipe_create, cred, pp, pp->pp_label); + MAC_PERFORM_NOSLEEP(pipe_create, cred, pp, pp->pp_label); } static void @@ -138,7 +138,7 @@ mac_pipe_relabel(struct ucred *cred, struct pipepair *pp, struct label *newlabel) { - MAC_PERFORM(pipe_relabel, cred, pp, pp->pp_label, newlabel); + MAC_PERFORM_NOSLEEP(pipe_relabel, cred, pp, pp->pp_label, newlabel); } MAC_CHECK_PROBE_DEFINE4(pipe_check_ioctl, "struct ucred *", @@ -152,7 +152,8 @@ mac_pipe_check_ioctl(struct ucred *cred, struct pipepair *pp, mtx_assert(&pp->pp_mtx, MA_OWNED); - MAC_CHECK(pipe_check_ioctl, cred, pp, pp->pp_label, cmd, data); + MAC_CHECK_NOSLEEP(pipe_check_ioctl, cred, pp, pp->pp_label, cmd, + data); MAC_CHECK_PROBE4(pipe_check_ioctl, error, cred, pp, cmd, data); return (error); @@ -168,7 +169,7 @@ mac_pipe_check_poll(struct ucred *cred, struct pipepair *pp) mtx_assert(&pp->pp_mtx, MA_OWNED); - MAC_CHECK(pipe_check_poll, cred, pp, pp->pp_label); + MAC_CHECK_NOSLEEP(pipe_check_poll, cred, pp, pp->pp_label); MAC_CHECK_PROBE2(pipe_check_poll, error, cred, pp); return (error); @@ -184,7 +185,7 @@ mac_pipe_check_read(struct ucred *cred, struct pipepair *pp) mtx_assert(&pp->pp_mtx, MA_OWNED); - MAC_CHECK(pipe_check_read, cred, pp, pp->pp_label); + MAC_CHECK_NOSLEEP(pipe_check_read, cred, pp, pp->pp_label); MAC_CHECK_PROBE2(pipe_check_read, error, cred, pp); return (error); @@ -201,7 +202,8 @@ mac_pipe_check_relabel(struct ucred *cred, struct pipepair *pp, mtx_assert(&pp->pp_mtx, MA_OWNED); - MAC_CHECK(pipe_check_relabel, cred, pp, pp->pp_label, newlabel); + MAC_CHECK_NOSLEEP(pipe_check_relabel, cred, pp, pp->pp_label, + newlabel); MAC_CHECK_PROBE3(pipe_check_relabel, error, cred, pp, newlabel); return (error); @@ -217,7 +219,7 @@ mac_pipe_check_stat(struct ucred *cred, struct pipepair *pp) mtx_assert(&pp->pp_mtx, MA_OWNED); - MAC_CHECK(pipe_check_stat, cred, pp, pp->pp_label); + MAC_CHECK_NOSLEEP(pipe_check_stat, cred, pp, pp->pp_label); MAC_CHECK_PROBE2(pipe_check_stat, error, cred, pp); return (error); @@ -233,7 +235,7 @@ mac_pipe_check_write(struct ucred *cred, struct pipepair *pp) mtx_assert(&pp->pp_mtx, MA_OWNED); - MAC_CHECK(pipe_check_write, cred, pp, pp->pp_label); + MAC_CHECK_NOSLEEP(pipe_check_write, cred, pp, pp->pp_label); MAC_CHECK_PROBE2(pipe_check_write, error, cred, pp); return (error); diff --git a/sys/security/mac/mac_posix_sem.c b/sys/security/mac/mac_posix_sem.c index 2e3560d..74a9ad9 100644 --- a/sys/security/mac/mac_posix_sem.c +++ b/sys/security/mac/mac_posix_sem.c @@ -80,7 +80,7 @@ static void mac_posixsem_label_free(struct label *label) { - MAC_PERFORM(posixsem_destroy_label, label); + MAC_PERFORM_NOSLEEP(posixsem_destroy_label, label); mac_labelzone_free(label); } @@ -98,7 +98,7 @@ void mac_posixsem_create(struct ucred *cred, struct ksem *ks) { - MAC_PERFORM(posixsem_create, cred, ks, ks->ks_label); + MAC_PERFORM_NOSLEEP(posixsem_create, cred, ks, ks->ks_label); } MAC_CHECK_PROBE_DEFINE2(posixsem_check_open, "struct ucred *", @@ -109,7 +109,7 @@ mac_posixsem_check_open(struct ucred *cred, struct ksem *ks) { int error; - MAC_CHECK(posixsem_check_open, cred, ks, ks->ks_label); + MAC_CHECK_NOSLEEP(posixsem_check_open, cred, ks, ks->ks_label); MAC_CHECK_PROBE2(posixsem_check_open, error, cred, ks); return (error); @@ -124,8 +124,8 @@ mac_posixsem_check_getvalue(struct ucred *active_cred, struct ucred *file_cred, { int error; - MAC_CHECK(posixsem_check_getvalue, active_cred, file_cred, ks, - ks->ks_label); + MAC_CHECK_NOSLEEP(posixsem_check_getvalue, active_cred, file_cred, + ks, ks->ks_label); MAC_CHECK_PROBE3(posixsem_check_getvalue, error, active_cred, file_cred, ks); @@ -141,7 +141,7 @@ mac_posixsem_check_post(struct ucred *active_cred, struct ucred *file_cred, { int error; - MAC_CHECK(posixsem_check_post, active_cred, file_cred, ks, + MAC_CHECK_NOSLEEP(posixsem_check_post, active_cred, file_cred, ks, ks->ks_label); MAC_CHECK_PROBE3(posixsem_check_post, error, active_cred, file_cred, ks); @@ -158,7 +158,7 @@ mac_posixsem_check_stat(struct ucred *active_cred, struct ucred *file_cred, { int error; - MAC_CHECK(posixsem_check_stat, active_cred, file_cred, ks, + MAC_CHECK_NOSLEEP(posixsem_check_stat, active_cred, file_cred, ks, ks->ks_label); MAC_CHECK_PROBE3(posixsem_check_stat, error, active_cred, file_cred, ks); @@ -174,7 +174,7 @@ mac_posixsem_check_unlink(struct ucred *cred, struct ksem *ks) { int error; - MAC_CHECK(posixsem_check_unlink, cred, ks, ks->ks_label); + MAC_CHECK_NOSLEEP(posixsem_check_unlink, cred, ks, ks->ks_label); MAC_CHECK_PROBE2(posixsem_check_unlink, error, cred, ks); return (error); @@ -189,7 +189,7 @@ mac_posixsem_check_wait(struct ucred *active_cred, struct ucred *file_cred, { int error; - MAC_CHECK(posixsem_check_wait, active_cred, file_cred, ks, + MAC_CHECK_NOSLEEP(posixsem_check_wait, active_cred, file_cred, ks, ks->ks_label); MAC_CHECK_PROBE3(posixsem_check_wait, error, active_cred, file_cred, ks); diff --git a/sys/security/mac/mac_posix_shm.c b/sys/security/mac/mac_posix_shm.c index 913cb43..bb9d9dd 100644 --- a/sys/security/mac/mac_posix_shm.c +++ b/sys/security/mac/mac_posix_shm.c @@ -79,7 +79,7 @@ static void mac_posixshm_label_free(struct label *label) { - MAC_PERFORM(posixshm_destroy_label, label); + MAC_PERFORM_NOSLEEP(posixshm_destroy_label, label); mac_labelzone_free(label); } @@ -97,7 +97,7 @@ void mac_posixshm_create(struct ucred *cred, struct shmfd *shmfd) { - MAC_PERFORM(posixshm_create, cred, shmfd, shmfd->shm_label); + MAC_PERFORM_NOSLEEP(posixshm_create, cred, shmfd, shmfd->shm_label); } MAC_CHECK_PROBE_DEFINE4(posixshm_check_mmap, "struct ucred *", @@ -109,8 +109,8 @@ mac_posixshm_check_mmap(struct ucred *cred, struct shmfd *shmfd, int prot, { int error; - MAC_CHECK(posixshm_check_mmap, cred, shmfd, shmfd->shm_label, prot, - flags); + MAC_CHECK_NOSLEEP(posixshm_check_mmap, cred, shmfd, shmfd->shm_label, + prot, flags); MAC_CHECK_PROBE4(posixshm_check_mmap, error, cred, shmfd, prot, flags); @@ -125,7 +125,7 @@ mac_posixshm_check_open(struct ucred *cred, struct shmfd *shmfd) { int error; - MAC_CHECK(posixshm_check_open, cred, shmfd, shmfd->shm_label); + MAC_CHECK_NOSLEEP(posixshm_check_open, cred, shmfd, shmfd->shm_label); MAC_CHECK_PROBE2(posixshm_check_open, error, cred, shmfd); return (error); @@ -140,7 +140,7 @@ mac_posixshm_check_stat(struct ucred *active_cred, struct ucred *file_cred, { int error; - MAC_CHECK(posixshm_check_stat, active_cred, file_cred, shmfd, + MAC_CHECK_NOSLEEP(posixshm_check_stat, active_cred, file_cred, shmfd, shmfd->shm_label); MAC_CHECK_PROBE3(posixshm_check_stat, error, active_cred, file_cred, shmfd); @@ -157,8 +157,8 @@ mac_posixshm_check_truncate(struct ucred *active_cred, struct ucred *file_cred, { int error; - MAC_CHECK(posixshm_check_truncate, active_cred, file_cred, shmfd, - shmfd->shm_label); + MAC_CHECK_NOSLEEP(posixshm_check_truncate, active_cred, file_cred, + shmfd, shmfd->shm_label); MAC_CHECK_PROBE3(posixshm_check_truncate, error, active_cred, file_cred, shmfd); @@ -173,7 +173,8 @@ mac_posixshm_check_unlink(struct ucred *cred, struct shmfd *shmfd) { int error; - MAC_CHECK(posixshm_check_unlink, cred, shmfd, shmfd->shm_label); + MAC_CHECK_NOSLEEP(posixshm_check_unlink, cred, shmfd, + shmfd->shm_label); MAC_CHECK_PROBE2(posixshm_check_unlink, error, cred, shmfd); return (error); diff --git a/sys/security/mac/mac_priv.c b/sys/security/mac/mac_priv.c index f12b020..afd64b9 100644 --- a/sys/security/mac/mac_priv.c +++ b/sys/security/mac/mac_priv.c @@ -72,7 +72,7 @@ mac_priv_check(struct ucred *cred, int priv) { int error; - MAC_CHECK(priv_check, cred, priv); + MAC_CHECK_NOSLEEP(priv_check, cred, priv); MAC_CHECK_PROBE2(priv_check, error, cred, priv); return (error); @@ -89,7 +89,7 @@ mac_priv_grant(struct ucred *cred, int priv) { int error; - MAC_GRANT(priv_grant, cred, priv); + MAC_GRANT_NOSLEEP(priv_grant, cred, priv); MAC_GRANT_PROBE2(priv_grant, error, cred, priv); return (error); diff --git a/sys/security/mac/mac_process.c b/sys/security/mac/mac_process.c index 7faa7ae..1c8ec64 100644 --- a/sys/security/mac/mac_process.c +++ b/sys/security/mac/mac_process.c @@ -112,7 +112,7 @@ static void mac_proc_label_free(struct label *label) { - MAC_PERFORM(proc_destroy_label, label); + MAC_PERFORM_NOSLEEP(proc_destroy_label, label); mac_labelzone_free(label); } @@ -386,7 +386,7 @@ mac_proc_check_debug(struct ucred *cred, struct proc *p) PROC_LOCK_ASSERT(p, MA_OWNED); - MAC_CHECK(proc_check_debug, cred, p); + MAC_CHECK_NOSLEEP(proc_check_debug, cred, p); MAC_CHECK_PROBE2(proc_check_debug, error, cred, p); return (error); @@ -401,7 +401,7 @@ mac_proc_check_sched(struct ucred *cred, struct proc *p) PROC_LOCK_ASSERT(p, MA_OWNED); - MAC_CHECK(proc_check_sched, cred, p); + MAC_CHECK_NOSLEEP(proc_check_sched, cred, p); MAC_CHECK_PROBE2(proc_check_sched, error, cred, p); return (error); @@ -417,7 +417,7 @@ mac_proc_check_signal(struct ucred *cred, struct proc *p, int signum) PROC_LOCK_ASSERT(p, MA_OWNED); - MAC_CHECK(proc_check_signal, cred, p, signum); + MAC_CHECK_NOSLEEP(proc_check_signal, cred, p, signum); MAC_CHECK_PROBE3(proc_check_signal, error, cred, p, signum); return (error); @@ -432,7 +432,7 @@ mac_proc_check_wait(struct ucred *cred, struct proc *p) PROC_LOCK_ASSERT(p, MA_OWNED); - MAC_CHECK(proc_check_wait, cred, p); + MAC_CHECK_NOSLEEP(proc_check_wait, cred, p); MAC_CHECK_PROBE2(proc_check_wait, error, cred, p); return (error); diff --git a/sys/security/mac/mac_socket.c b/sys/security/mac/mac_socket.c index e73ce12..fa24499 100644 --- a/sys/security/mac/mac_socket.c +++ b/sys/security/mac/mac_socket.c @@ -100,9 +100,12 @@ mac_socket_label_alloc(int flag) if (label == NULL) return (NULL); - MAC_CHECK(socket_init_label, label, flag); + if (flag & M_WAITOK) + MAC_CHECK(socket_init_label, label, flag); + else + MAC_CHECK_NOSLEEP(socket_init_label, label, flag); if (error) { - MAC_PERFORM(socket_destroy_label, label); + MAC_PERFORM_NOSLEEP(socket_destroy_label, label); mac_labelzone_free(label); return (NULL); } @@ -119,9 +122,12 @@ mac_socketpeer_label_alloc(int flag) if (label == NULL) return (NULL); - MAC_CHECK(socketpeer_init_label, label, flag); + if (flag & M_WAITOK) + MAC_CHECK(socketpeer_init_label, label, flag); + else + MAC_CHECK_NOSLEEP(socketpeer_init_label, label, flag); if (error) { - MAC_PERFORM(socketpeer_destroy_label, label); + MAC_PERFORM_NOSLEEP(socketpeer_destroy_label, label); mac_labelzone_free(label); return (NULL); } @@ -153,7 +159,7 @@ void mac_socket_label_free(struct label *label) { - MAC_PERFORM(socket_destroy_label, label); + MAC_PERFORM_NOSLEEP(socket_destroy_label, label); mac_labelzone_free(label); } @@ -161,7 +167,7 @@ static void mac_socketpeer_label_free(struct label *label) { - MAC_PERFORM(socketpeer_destroy_label, label); + MAC_PERFORM_NOSLEEP(socketpeer_destroy_label, label); mac_labelzone_free(label); } @@ -181,7 +187,7 @@ void mac_socket_copy_label(struct label *src, struct label *dest) { - MAC_PERFORM(socket_copy_label, src, dest); + MAC_PERFORM_NOSLEEP(socket_copy_label, src, dest); } int @@ -220,7 +226,7 @@ void mac_socket_create(struct ucred *cred, struct socket *so) { - MAC_PERFORM(socket_create, cred, so, so->so_label); + MAC_PERFORM_NOSLEEP(socket_create, cred, so, so->so_label); } void @@ -229,7 +235,7 @@ mac_socket_newconn(struct socket *oldso, struct socket *newso) SOCK_LOCK_ASSERT(oldso); - MAC_PERFORM(socket_newconn, oldso, oldso->so_label, newso, + MAC_PERFORM_NOSLEEP(socket_newconn, oldso, oldso->so_label, newso, newso->so_label); } @@ -240,7 +246,8 @@ mac_socket_relabel(struct ucred *cred, struct socket *so, SOCK_LOCK_ASSERT(so); - MAC_PERFORM(socket_relabel, cred, so, so->so_label, newlabel); + MAC_PERFORM_NOSLEEP(socket_relabel, cred, so, so->so_label, + newlabel); } void @@ -252,7 +259,7 @@ mac_socketpeer_set_from_mbuf(struct mbuf *m, struct socket *so) label = mac_mbuf_to_label(m); - MAC_PERFORM(socketpeer_set_from_mbuf, m, label, so, + MAC_PERFORM_NOSLEEP(socketpeer_set_from_mbuf, m, label, so, so->so_peerlabel); } @@ -265,8 +272,8 @@ mac_socketpeer_set_from_socket(struct socket *oldso, struct socket *newso) * is the original, and one is the new. However, it's called in both * directions, so we can't assert the lock here currently. */ - MAC_PERFORM(socketpeer_set_from_socket, oldso, oldso->so_label, - newso, newso->so_peerlabel); + MAC_PERFORM_NOSLEEP(socketpeer_set_from_socket, oldso, + oldso->so_label, newso, newso->so_peerlabel); } void @@ -278,7 +285,7 @@ mac_socket_create_mbuf(struct socket *so, struct mbuf *m) label = mac_mbuf_to_label(m); - MAC_PERFORM(socket_create_mbuf, so, so->so_label, m, label); + MAC_PERFORM_NOSLEEP(socket_create_mbuf, so, so->so_label, m, label); } MAC_CHECK_PROBE_DEFINE2(socket_check_accept, "struct ucred *", @@ -291,7 +298,7 @@ mac_socket_check_accept(struct ucred *cred, struct socket *so) SOCK_LOCK_ASSERT(so); - MAC_CHECK(socket_check_accept, cred, so, so->so_label); + MAC_CHECK_NOSLEEP(socket_check_accept, cred, so, so->so_label); MAC_CHECK_PROBE2(socket_check_accept, error, cred, so); return (error); @@ -308,7 +315,7 @@ mac_socket_check_bind(struct ucred *cred, struct socket *so, SOCK_LOCK_ASSERT(so); - MAC_CHECK(socket_check_bind, cred, so, so->so_label, sa); + MAC_CHECK_NOSLEEP(socket_check_bind, cred, so, so->so_label, sa); MAC_CHECK_PROBE3(socket_check_bind, error, cred, so, sa); return (error); @@ -325,7 +332,7 @@ mac_socket_check_connect(struct ucred *cred, struct socket *so, SOCK_LOCK_ASSERT(so); - MAC_CHECK(socket_check_connect, cred, so, so->so_label, sa); + MAC_CHECK_NOSLEEP(socket_check_connect, cred, so, so->so_label, sa); MAC_CHECK_PROBE3(socket_check_connect, error, cred, so, sa); return (error); @@ -339,7 +346,7 @@ mac_socket_check_create(struct ucred *cred, int domain, int type, int proto) { int error; - MAC_CHECK(socket_check_create, cred, domain, type, proto); + MAC_CHECK_NOSLEEP(socket_check_create, cred, domain, type, proto); MAC_CHECK_PROBE4(socket_check_create, error, cred, domain, type, proto); @@ -359,7 +366,7 @@ mac_socket_check_deliver(struct socket *so, struct mbuf *m) label = mac_mbuf_to_label(m); - MAC_CHECK(socket_check_deliver, so, so->so_label, m, label); + MAC_CHECK_NOSLEEP(socket_check_deliver, so, so->so_label, m, label); MAC_CHECK_PROBE2(socket_check_deliver, error, so, m); return (error); @@ -375,7 +382,7 @@ mac_socket_check_listen(struct ucred *cred, struct socket *so) SOCK_LOCK_ASSERT(so); - MAC_CHECK(socket_check_listen, cred, so, so->so_label); + MAC_CHECK_NOSLEEP(socket_check_listen, cred, so, so->so_label); MAC_CHECK_PROBE2(socket_check_listen, error, cred, so); return (error); @@ -391,7 +398,7 @@ mac_socket_check_poll(struct ucred *cred, struct socket *so) SOCK_LOCK_ASSERT(so); - MAC_CHECK(socket_check_poll, cred, so, so->so_label); + MAC_CHECK_NOSLEEP(socket_check_poll, cred, so, so->so_label); MAC_CHECK_PROBE2(socket_check_poll, error, cred, so); return (error); @@ -407,7 +414,7 @@ mac_socket_check_receive(struct ucred *cred, struct socket *so) SOCK_LOCK_ASSERT(so); - MAC_CHECK(socket_check_receive, cred, so, so->so_label); + MAC_CHECK_NOSLEEP(socket_check_receive, cred, so, so->so_label); MAC_CHECK_PROBE2(socket_check_receive, error, cred, so); return (error); @@ -424,7 +431,8 @@ mac_socket_check_relabel(struct ucred *cred, struct socket *so, SOCK_LOCK_ASSERT(so); - MAC_CHECK(socket_check_relabel, cred, so, so->so_label, newlabel); + MAC_CHECK_NOSLEEP(socket_check_relabel, cred, so, so->so_label, + newlabel); MAC_CHECK_PROBE3(socket_check_relabel, error, cred, so, newlabel); return (error); @@ -440,7 +448,7 @@ mac_socket_check_send(struct ucred *cred, struct socket *so) SOCK_LOCK_ASSERT(so); - MAC_CHECK(socket_check_send, cred, so, so->so_label); + MAC_CHECK_NOSLEEP(socket_check_send, cred, so, so->so_label); MAC_CHECK_PROBE2(socket_check_send, error, cred, so); return (error); @@ -456,7 +464,7 @@ mac_socket_check_stat(struct ucred *cred, struct socket *so) SOCK_LOCK_ASSERT(so); - MAC_CHECK(socket_check_stat, cred, so, so->so_label); + MAC_CHECK_NOSLEEP(socket_check_stat, cred, so, so->so_label); MAC_CHECK_PROBE2(socket_check_stat, error, cred, so); return (error); @@ -472,7 +480,7 @@ mac_socket_check_visible(struct ucred *cred, struct socket *so) SOCK_LOCK_ASSERT(so); - MAC_CHECK(socket_check_visible, cred, so, so->so_label); + MAC_CHECK_NOSLEEP(socket_check_visible, cred, so, so->so_label); MAC_CHECK_PROBE2(socket_check_visible, error, cred, so); return (error); diff --git a/sys/security/mac/mac_syscalls.c b/sys/security/mac/mac_syscalls.c index c4b0606..905c43b 100644 --- a/sys/security/mac/mac_syscalls.c +++ b/sys/security/mac/mac_syscalls.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 1999-2002, 2006 Robert N. M. Watson + * Copyright (c) 1999-2002, 2006, 2009 Robert N. M. Watson * Copyright (c) 2001 Ilmar S. Habibulin * Copyright (c) 2001-2005 Networks Associates Technology, Inc. * Copyright (c) 2005-2006 SPARTA, Inc. @@ -17,6 +17,9 @@ * This software was enhanced by SPARTA ISSO under SPAWAR contract * N66001-04-C-6019 ("SEFOS"). * + * This software was developed at the University of Cambridge Computer + * Laboratory with support from a grant from Google, Inc. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -617,7 +620,7 @@ mac_syscall(struct thread *td, struct mac_syscall_args *uap) { struct mac_policy_conf *mpc; char target[MAC_MAX_POLICY_NAME]; - int entrycount, error; + int error; error = copyinstr(uap->policy, target, sizeof(target), NULL); if (error) @@ -633,7 +636,8 @@ mac_syscall(struct thread *td, struct mac_syscall_args *uap) } } - if ((entrycount = mac_policy_list_conditional_busy()) != 0) { + if (!LIST_EMPTY(&mac_policy_list)) { + mac_policy_slock_sleep(); LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { if (strcmp(mpc->mpc_name, target) == 0 && mpc->mpc_ops->mpo_syscall != NULL) { @@ -642,7 +646,7 @@ mac_syscall(struct thread *td, struct mac_syscall_args *uap) break; } } - mac_policy_list_unbusy(); + mac_policy_sunlock_sleep(); } out: return (error); diff --git a/sys/security/mac/mac_system.c b/sys/security/mac/mac_system.c index a8e351e..4a377c0 100644 --- a/sys/security/mac/mac_system.c +++ b/sys/security/mac/mac_system.c @@ -78,7 +78,7 @@ mac_kenv_check_dump(struct ucred *cred) { int error; - MAC_CHECK(kenv_check_dump, cred); + MAC_CHECK_NOSLEEP(kenv_check_dump, cred); MAC_CHECK_PROBE1(kenv_check_dump, error, cred); return (error); @@ -91,7 +91,7 @@ mac_kenv_check_get(struct ucred *cred, char *name) { int error; - MAC_CHECK(kenv_check_get, cred, name); + MAC_CHECK_NOSLEEP(kenv_check_get, cred, name); MAC_CHECK_PROBE2(kenv_check_get, error, cred, name); return (error); @@ -105,7 +105,7 @@ mac_kenv_check_set(struct ucred *cred, char *name, char *value) { int error; - MAC_CHECK(kenv_check_set, cred, name, value); + MAC_CHECK_NOSLEEP(kenv_check_set, cred, name, value); MAC_CHECK_PROBE3(kenv_check_set, error, cred, name, value); return (error); @@ -118,7 +118,7 @@ mac_kenv_check_unset(struct ucred *cred, char *name) { int error; - MAC_CHECK(kenv_check_unset, cred, name); + MAC_CHECK_NOSLEEP(kenv_check_unset, cred, name); MAC_CHECK_PROBE2(kenv_check_unset, error, cred, name); return (error); @@ -146,7 +146,7 @@ mac_kld_check_stat(struct ucred *cred) { int error; - MAC_CHECK(kld_check_stat, cred); + MAC_CHECK_NOSLEEP(kld_check_stat, cred); MAC_CHECK_PROBE1(kld_check_stat, error, cred); return (error); @@ -178,7 +178,7 @@ mac_system_check_reboot(struct ucred *cred, int howto) { int error; - MAC_CHECK(system_check_reboot, cred, howto); + MAC_CHECK_NOSLEEP(system_check_reboot, cred, howto); MAC_CHECK_PROBE2(system_check_reboot, error, cred, howto); return (error); @@ -229,7 +229,7 @@ mac_system_check_sysctl(struct ucred *cred, struct sysctl_oid *oidp, * XXXMAC: We would very much like to assert the SYSCTL_LOCK here, * but since it's not exported from kern_sysctl.c, we can't. */ - MAC_CHECK(system_check_sysctl, cred, oidp, arg1, arg2, req); + MAC_CHECK_NOSLEEP(system_check_sysctl, cred, oidp, arg1, arg2, req); MAC_CHECK_PROBE3(system_check_sysctl, error, cred, oidp, req); return (error); diff --git a/sys/security/mac/mac_sysv_msg.c b/sys/security/mac/mac_sysv_msg.c index 1053871..a1d21d9 100644 --- a/sys/security/mac/mac_sysv_msg.c +++ b/sys/security/mac/mac_sysv_msg.c @@ -107,7 +107,7 @@ static void mac_sysv_msgmsg_label_free(struct label *label) { - MAC_PERFORM(sysvmsg_destroy_label, label); + MAC_PERFORM_NOSLEEP(sysvmsg_destroy_label, label); mac_labelzone_free(label); } @@ -125,7 +125,7 @@ static void mac_sysv_msgqueue_label_free(struct label *label) { - MAC_PERFORM(sysvmsq_destroy_label, label); + MAC_PERFORM_NOSLEEP(sysvmsq_destroy_label, label); mac_labelzone_free(label); } @@ -144,7 +144,7 @@ mac_sysvmsg_create(struct ucred *cred, struct msqid_kernel *msqkptr, struct msg *msgptr) { - MAC_PERFORM(sysvmsg_create, cred, msqkptr, msqkptr->label, + MAC_PERFORM_NOSLEEP(sysvmsg_create, cred, msqkptr, msqkptr->label, msgptr, msgptr->label); } @@ -152,21 +152,21 @@ void mac_sysvmsq_create(struct ucred *cred, struct msqid_kernel *msqkptr) { - MAC_PERFORM(sysvmsq_create, cred, msqkptr, msqkptr->label); + MAC_PERFORM_NOSLEEP(sysvmsq_create, cred, msqkptr, msqkptr->label); } void mac_sysvmsg_cleanup(struct msg *msgptr) { - MAC_PERFORM(sysvmsg_cleanup, msgptr->label); + MAC_PERFORM_NOSLEEP(sysvmsg_cleanup, msgptr->label); } void mac_sysvmsq_cleanup(struct msqid_kernel *msqkptr) { - MAC_PERFORM(sysvmsq_cleanup, msqkptr->label); + MAC_PERFORM_NOSLEEP(sysvmsq_cleanup, msqkptr->label); } MAC_CHECK_PROBE_DEFINE3(sysvmsq_check_msgmsq, "struct ucred *", @@ -178,7 +178,7 @@ mac_sysvmsq_check_msgmsq(struct ucred *cred, struct msg *msgptr, { int error; - MAC_CHECK(sysvmsq_check_msgmsq, cred, msgptr, msgptr->label, + MAC_CHECK_NOSLEEP(sysvmsq_check_msgmsq, cred, msgptr, msgptr->label, msqkptr, msqkptr->label); MAC_CHECK_PROBE3(sysvmsq_check_msgmsq, error, cred, msgptr, msqkptr); @@ -193,7 +193,7 @@ mac_sysvmsq_check_msgrcv(struct ucred *cred, struct msg *msgptr) { int error; - MAC_CHECK(sysvmsq_check_msgrcv, cred, msgptr, msgptr->label); + MAC_CHECK_NOSLEEP(sysvmsq_check_msgrcv, cred, msgptr, msgptr->label); MAC_CHECK_PROBE2(sysvmsq_check_msgrcv, error, cred, msgptr); return (error); @@ -207,7 +207,8 @@ mac_sysvmsq_check_msgrmid(struct ucred *cred, struct msg *msgptr) { int error; - MAC_CHECK(sysvmsq_check_msgrmid, cred, msgptr, msgptr->label); + MAC_CHECK_NOSLEEP(sysvmsq_check_msgrmid, cred, msgptr, + msgptr->label); MAC_CHECK_PROBE2(sysvmsq_check_msgrmid, error, cred, msgptr); return (error); @@ -221,7 +222,8 @@ mac_sysvmsq_check_msqget(struct ucred *cred, struct msqid_kernel *msqkptr) { int error; - MAC_CHECK(sysvmsq_check_msqget, cred, msqkptr, msqkptr->label); + MAC_CHECK_NOSLEEP(sysvmsq_check_msqget, cred, msqkptr, + msqkptr->label); MAC_CHECK_PROBE2(sysvmsq_check_msqget, error, cred, msqkptr); return (error); @@ -235,7 +237,8 @@ mac_sysvmsq_check_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr) { int error; - MAC_CHECK(sysvmsq_check_msqsnd, cred, msqkptr, msqkptr->label); + MAC_CHECK_NOSLEEP(sysvmsq_check_msqsnd, cred, msqkptr, + msqkptr->label); MAC_CHECK_PROBE2(sysvmsq_check_msqsnd, error, cred, msqkptr); return (error); @@ -249,7 +252,8 @@ mac_sysvmsq_check_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr) { int error; - MAC_CHECK(sysvmsq_check_msqrcv, cred, msqkptr, msqkptr->label); + MAC_CHECK_NOSLEEP(sysvmsq_check_msqrcv, cred, msqkptr, + msqkptr->label); MAC_CHECK_PROBE2(sysvmsq_check_msqrcv, error, cred, msqkptr); return (error); @@ -264,7 +268,8 @@ mac_sysvmsq_check_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr, { int error; - MAC_CHECK(sysvmsq_check_msqctl, cred, msqkptr, msqkptr->label, cmd); + MAC_CHECK_NOSLEEP(sysvmsq_check_msqctl, cred, msqkptr, + msqkptr->label, cmd); MAC_CHECK_PROBE3(sysvmsq_check_msqctl, error, cred, msqkptr, cmd); return (error); diff --git a/sys/security/mac/mac_sysv_sem.c b/sys/security/mac/mac_sysv_sem.c index 9fc13fa..add17da 100644 --- a/sys/security/mac/mac_sysv_sem.c +++ b/sys/security/mac/mac_sysv_sem.c @@ -86,7 +86,7 @@ static void mac_sysv_sem_label_free(struct label *label) { - MAC_PERFORM(sysvsem_destroy_label, label); + MAC_PERFORM_NOSLEEP(sysvsem_destroy_label, label); mac_labelzone_free(label); } @@ -104,14 +104,14 @@ void mac_sysvsem_create(struct ucred *cred, struct semid_kernel *semakptr) { - MAC_PERFORM(sysvsem_create, cred, semakptr, semakptr->label); + MAC_PERFORM_NOSLEEP(sysvsem_create, cred, semakptr, semakptr->label); } void mac_sysvsem_cleanup(struct semid_kernel *semakptr) { - MAC_PERFORM(sysvsem_cleanup, semakptr->label); + MAC_PERFORM_NOSLEEP(sysvsem_cleanup, semakptr->label); } MAC_CHECK_PROBE_DEFINE3(sysvsem_check_semctl, "struct ucred *", @@ -123,8 +123,8 @@ mac_sysvsem_check_semctl(struct ucred *cred, struct semid_kernel *semakptr, { int error; - MAC_CHECK(sysvsem_check_semctl, cred, semakptr, semakptr->label, - cmd); + MAC_CHECK_NOSLEEP(sysvsem_check_semctl, cred, semakptr, + semakptr->label, cmd); MAC_CHECK_PROBE3(sysvsem_check_semctl, error, cred, semakptr, cmd); return (error); @@ -138,7 +138,8 @@ mac_sysvsem_check_semget(struct ucred *cred, struct semid_kernel *semakptr) { int error; - MAC_CHECK(sysvsem_check_semget, cred, semakptr, semakptr->label); + MAC_CHECK_NOSLEEP(sysvsem_check_semget, cred, semakptr, + semakptr->label); return (error); } @@ -152,8 +153,8 @@ mac_sysvsem_check_semop(struct ucred *cred, struct semid_kernel *semakptr, { int error; - MAC_CHECK(sysvsem_check_semop, cred, semakptr, semakptr->label, - accesstype); + MAC_CHECK_NOSLEEP(sysvsem_check_semop, cred, semakptr, + semakptr->label, accesstype); MAC_CHECK_PROBE3(sysvsem_check_semop, error, cred, semakptr, accesstype); diff --git a/sys/security/mac/mac_sysv_shm.c b/sys/security/mac/mac_sysv_shm.c index d42cb0b..57c2264 100644 --- a/sys/security/mac/mac_sysv_shm.c +++ b/sys/security/mac/mac_sysv_shm.c @@ -86,7 +86,7 @@ static void mac_sysv_shm_label_free(struct label *label) { - MAC_PERFORM(sysvshm_destroy_label, label); + MAC_PERFORM_NOSLEEP(sysvshm_destroy_label, label); mac_labelzone_free(label); } @@ -104,14 +104,15 @@ void mac_sysvshm_create(struct ucred *cred, struct shmid_kernel *shmsegptr) { - MAC_PERFORM(sysvshm_create, cred, shmsegptr, shmsegptr->label); + MAC_PERFORM_NOSLEEP(sysvshm_create, cred, shmsegptr, + shmsegptr->label); } void mac_sysvshm_cleanup(struct shmid_kernel *shmsegptr) { - MAC_PERFORM(sysvshm_cleanup, shmsegptr->label); + MAC_PERFORM_NOSLEEP(sysvshm_cleanup, shmsegptr->label); } MAC_CHECK_PROBE_DEFINE3(sysvshm_check_shmat, "struct ucred *", @@ -123,8 +124,8 @@ mac_sysvshm_check_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr, { int error; - MAC_CHECK(sysvshm_check_shmat, cred, shmsegptr, shmsegptr->label, - shmflg); + MAC_CHECK_NOSLEEP(sysvshm_check_shmat, cred, shmsegptr, + shmsegptr->label, shmflg); MAC_CHECK_PROBE3(sysvshm_check_shmat, error, cred, shmsegptr, shmflg); @@ -140,8 +141,8 @@ mac_sysvshm_check_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr, { int error; - MAC_CHECK(sysvshm_check_shmctl, cred, shmsegptr, shmsegptr->label, - cmd); + MAC_CHECK_NOSLEEP(sysvshm_check_shmctl, cred, shmsegptr, + shmsegptr->label, cmd); MAC_CHECK_PROBE3(sysvshm_check_shmctl, error, cred, shmsegptr, cmd); return (error); @@ -155,7 +156,8 @@ mac_sysvshm_check_shmdt(struct ucred *cred, struct shmid_kernel *shmsegptr) { int error; - MAC_CHECK(sysvshm_check_shmdt, cred, shmsegptr, shmsegptr->label); + MAC_CHECK_NOSLEEP(sysvshm_check_shmdt, cred, shmsegptr, + shmsegptr->label); MAC_CHECK_PROBE2(sysvshm_check_shmdt, error, cred, shmsegptr); return (error); @@ -170,8 +172,8 @@ mac_sysvshm_check_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr, { int error; - MAC_CHECK(sysvshm_check_shmget, cred, shmsegptr, shmsegptr->label, - shmflg); + MAC_CHECK_NOSLEEP(sysvshm_check_shmget, cred, shmsegptr, + shmsegptr->label, shmflg); MAC_CHECK_PROBE3(sysvshm_check_shmget, error, cred, shmsegptr, shmflg); diff --git a/sys/security/mac/mac_vfs.c b/sys/security/mac/mac_vfs.c index 01afb81..0cb0f15 100644 --- a/sys/security/mac/mac_vfs.c +++ b/sys/security/mac/mac_vfs.c @@ -150,7 +150,7 @@ static void mac_devfs_label_free(struct label *label) { - MAC_PERFORM(devfs_destroy_label, label); + MAC_PERFORM_NOSLEEP(devfs_destroy_label, label); mac_labelzone_free(label); } @@ -168,7 +168,7 @@ static void mac_mount_label_free(struct label *label) { - MAC_PERFORM(mount_destroy_label, label); + MAC_PERFORM_NOSLEEP(mount_destroy_label, label); mac_labelzone_free(label); } @@ -186,7 +186,7 @@ void mac_vnode_label_free(struct label *label) { - MAC_PERFORM(vnode_destroy_label, label); + MAC_PERFORM_NOSLEEP(vnode_destroy_label, label); mac_labelzone_free(label); } @@ -204,7 +204,7 @@ void mac_vnode_copy_label(struct label *src, struct label *dest) { - MAC_PERFORM(vnode_copy_label, src, dest); + MAC_PERFORM_NOSLEEP(vnode_copy_label, src, dest); } int @@ -232,7 +232,8 @@ void mac_devfs_update(struct mount *mp, struct devfs_dirent *de, struct vnode *vp) { - MAC_PERFORM(devfs_update, mp, de, de->de_label, vp, vp->v_label); + MAC_PERFORM_NOSLEEP(devfs_update, mp, de, de->de_label, vp, + vp->v_label); } void @@ -240,7 +241,7 @@ mac_devfs_vnode_associate(struct mount *mp, struct devfs_dirent *de, struct vnode *vp) { - MAC_PERFORM(devfs_vnode_associate, mp, mp->mnt_label, de, + MAC_PERFORM_NOSLEEP(devfs_vnode_associate, mp, mp->mnt_label, de, de->de_label, vp, vp->v_label); } @@ -261,8 +262,8 @@ void mac_vnode_associate_singlelabel(struct mount *mp, struct vnode *vp) { - MAC_PERFORM(vnode_associate_singlelabel, mp, mp->mnt_label, vp, - vp->v_label); + MAC_PERFORM_NOSLEEP(vnode_associate_singlelabel, mp, mp->mnt_label, + vp, vp->v_label); } /* @@ -360,8 +361,9 @@ mac_vnode_execve_will_transition(struct ucred *old, struct vnode *vp, ASSERT_VOP_LOCKED(vp, "mac_vnode_execve_will_transition"); result = 0; - MAC_BOOLEAN(vnode_execve_will_transition, ||, old, vp, vp->v_label, - interpvplabel, imgp, imgp->execlabel); + /* No sleeping since the process lock will be held by the caller. */ + MAC_BOOLEAN_NOSLEEP(vnode_execve_will_transition, ||, old, vp, + vp->v_label, interpvplabel, imgp, imgp->execlabel); return (result); } @@ -960,7 +962,7 @@ mac_mount_check_stat(struct ucred *cred, struct mount *mount) { int error; - MAC_CHECK(mount_check_stat, cred, mount, mount->mnt_label); + MAC_CHECK_NOSLEEP(mount_check_stat, cred, mount, mount->mnt_label); MAC_CHECK_PROBE2(mount_check_stat, error, cred, mount); return (error); @@ -971,7 +973,8 @@ mac_devfs_create_device(struct ucred *cred, struct mount *mp, struct cdev *dev, struct devfs_dirent *de) { - MAC_PERFORM(devfs_create_device, cred, mp, dev, de, de->de_label); + MAC_PERFORM_NOSLEEP(devfs_create_device, cred, mp, dev, de, + de->de_label); } void @@ -979,8 +982,8 @@ mac_devfs_create_symlink(struct ucred *cred, struct mount *mp, struct devfs_dirent *dd, struct devfs_dirent *de) { - MAC_PERFORM(devfs_create_symlink, cred, mp, dd, dd->de_label, de, - de->de_label); + MAC_PERFORM_NOSLEEP(devfs_create_symlink, cred, mp, dd, + dd->de_label, de, de->de_label); } void @@ -988,8 +991,8 @@ mac_devfs_create_directory(struct mount *mp, char *dirname, int dirnamelen, struct devfs_dirent *de) { - MAC_PERFORM(devfs_create_directory, mp, dirname, dirnamelen, de, - de->de_label); + MAC_PERFORM_NOSLEEP(devfs_create_directory, mp, dirname, dirnamelen, + de, de->de_label); } /* |