summaryrefslogtreecommitdiffstats
path: root/sys/security/mac_portacl
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2004-12-06 19:43:45 +0000
committerrwatson <rwatson@FreeBSD.org>2004-12-06 19:43:45 +0000
commit892d4bfa16f4e9d3a0694b822687fe4b7caef873 (patch)
tree8374e7eb74870c02b47fadcc940d9a26b61d48fb /sys/security/mac_portacl
parent83e7e80417809f4f9600e08a588bc1de7f5128b2 (diff)
downloadFreeBSD-src-892d4bfa16f4e9d3a0694b822687fe4b7caef873.zip
FreeBSD-src-892d4bfa16f4e9d3a0694b822687fe4b7caef873.tar.gz
Switch from using an sx lock to a mutex for the mac_portacl rule chain:
the sx lock was used previously because we might sleep allocating additional memory by using auto-extending sbufs. However, we no longer do this, instead retaining the user-submitted rule string, so mutexes can be used instead. Annotate the reason for not using the sbuf-related rule-to-string code with a comment. Switch to using TAILQ_CONCAT() instead of manual list copying, as it's O(1), reducing the rule replacement step under the mutex from O(2N) to O(2). Remove now uneeded vnode-related includes. MFC after: 2 weeks
Diffstat (limited to 'sys/security/mac_portacl')
-rw-r--r--sys/security/mac_portacl/mac_portacl.c45
1 files changed, 19 insertions, 26 deletions
diff --git a/sys/security/mac_portacl/mac_portacl.c b/sys/security/mac_portacl/mac_portacl.c
index 7524155..c7551bb 100644
--- a/sys/security/mac_portacl/mac_portacl.c
+++ b/sys/security/mac_portacl/mac_portacl.c
@@ -61,21 +61,21 @@
#include <sys/domain.h>
#include <sys/kernel.h>
#include <sys/libkern.h>
+#include <sys/lock.h>
#include <sys/mac.h>
#include <sys/malloc.h>
#include <sys/mount.h>
+#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/protosw.h>
#include <sys/queue.h>
#include <sys/systm.h>
#include <sys/sysproto.h>
#include <sys/sysent.h>
-#include <sys/vnode.h>
#include <sys/file.h>
#include <sys/sbuf.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
-#include <sys/sx.h>
#include <sys/sysctl.h>
#include <netinet/in.h>
@@ -134,7 +134,7 @@ struct rule {
* for the specified binding.
*/
-static struct sx rule_sx;
+static struct mtx rule_mtx;
static TAILQ_HEAD(rulehead, rule) rule_head;
static char rule_string[MAC_RULE_STRING_LEN];
@@ -157,7 +157,7 @@ static void
destroy(struct mac_policy_conf *mpc)
{
- sx_destroy(&rule_sx);
+ mtx_destroy(&rule_mtx);
toast_rules(&rule_head);
}
@@ -165,7 +165,7 @@ static void
init(struct mac_policy_conf *mpc)
{
- sx_init(&rule_sx, "rule_sx");
+ mtx_init(&rule_mtx, "rule_mtx", NULL, MTX_DEF);
TAILQ_INIT(&rule_head);
}
@@ -260,6 +260,12 @@ out:
return (error);
}
+/*
+ * rule_printf() and rules_to_string() are unused currently because they rely
+ * on sbufs with auto-extension, which may sleep while holding a mutex.
+ * Instead, the non-canonical user-generated rule string is returned to the
+ * user when the rules are queried, which is faster anyway.
+ */
#if 0
static void
rule_printf(struct sbuf *sb, struct rule *rule)
@@ -302,7 +308,7 @@ rules_to_string(void)
sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
needcomma = 0;
- sx_slock(&rule_sx);
+ mtx_lock(&rule_mtx);
for (rule = TAILQ_FIRST(&rule_head); rule != NULL;
rule = TAILQ_NEXT(rule, r_entries)) {
if (!needcomma)
@@ -311,7 +317,7 @@ rules_to_string(void)
sbuf_printf(sb, ",");
rule_printf(sb, rule);
}
- sx_sunlock(&rule_sx);
+ mtx_unlock(&rule_mtx);
sbuf_finish(sb);
temp = strdup(sbuf_data(sb), M_PORTACL);
sbuf_delete(sb);
@@ -328,7 +334,6 @@ sysctl_rules(SYSCTL_HANDLER_ARGS)
{
char *string, *copy_string, *new_string;
struct rulehead head, save_head;
- struct rule *rule;
int error;
new_string = NULL;
@@ -353,23 +358,11 @@ sysctl_rules(SYSCTL_HANDLER_ARGS)
goto out;
TAILQ_INIT(&save_head);
- sx_xlock(&rule_sx);
- /*
- * XXX: Unfortunately, TAILQ doesn't yet have a supported
- * assignment operator to copy one queue to another, due
- * to a self-referential pointer in the tailq header.
- * For now, do it the old-fashioned way.
- */
- while ((rule = TAILQ_FIRST(&rule_head)) != NULL) {
- TAILQ_REMOVE(&rule_head, rule, r_entries);
- TAILQ_INSERT_HEAD(&save_head, rule, r_entries);
- }
- while ((rule = TAILQ_FIRST(&head)) != NULL) {
- TAILQ_REMOVE(&head, rule, r_entries);
- TAILQ_INSERT_HEAD(&rule_head, rule, r_entries);
- }
+ mtx_lock(&rule_mtx);
+ TAILQ_CONCAT(&save_head, &rule_head, r_entries);
+ TAILQ_CONCAT(&rule_head, &head, r_entries);
strcpy(rule_string, string);
- sx_xunlock(&rule_sx);
+ mtx_unlock(&rule_mtx);
toast_rules(&save_head);
}
out:
@@ -396,7 +389,7 @@ rules_check(struct ucred *cred, int family, int type, u_int16_t port)
return (0);
error = EPERM;
- sx_slock(&rule_sx);
+ mtx_lock(&rule_mtx);
for (rule = TAILQ_FIRST(&rule_head);
rule != NULL;
rule = TAILQ_NEXT(rule, r_entries)) {
@@ -423,7 +416,7 @@ rules_check(struct ucred *cred, int family, int type, u_int16_t port)
panic("rules_check: unknown rule type %d",
rule->r_idtype);
}
- sx_sunlock(&rule_sx);
+ mtx_unlock(&rule_mtx);
if (error != 0 && mac_portacl_suser_exempt != 0)
error = suser_cred(cred, 0);
OpenPOWER on IntegriCloud