All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/2] Series short description
@ 2008-04-10 14:48 Paul Moore
  2008-04-10 14:48 ` [PATCH v3 1/2] SELinux: Made netnode cache adds faster Paul Moore
  2008-04-10 14:48 ` [PATCH v3 2/2] SELinux: Add network port SID cache Paul Moore
  0 siblings, 2 replies; 8+ messages in thread
From: Paul Moore @ 2008-04-10 14:48 UTC (permalink / raw
  To: selinux

This revision includes the list_del_rcu() fix mentioned earlier this
morning.  This boots on a quasi-recent Rawhide machine (three/four days
old?) with the targeted policy in enforcing mode with no noticeable
regressions to networking: I can do a wget to google, SSH into the
machine, ping, etc..

-- 
paul moore
linux security @ hp

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v3 1/2] SELinux: Made netnode cache adds faster
  2008-04-10 14:48 [PATCH v3 0/2] Series short description Paul Moore
@ 2008-04-10 14:48 ` Paul Moore
  2008-04-11 18:23   ` Stephen Smalley
  2008-04-10 14:48 ` [PATCH v3 2/2] SELinux: Add network port SID cache Paul Moore
  1 sibling, 1 reply; 8+ messages in thread
From: Paul Moore @ 2008-04-10 14:48 UTC (permalink / raw
  To: selinux

When adding new entries to the network node cache we would walk the entire
hash bucket to make sure we didn't cross a threshold (done to bound the cache
size).  This isn't a very quick or elegant solution for something which is
supposed to be quick-ish so add a counter to each hash bucket to track the
size of the bucket and eliminate the need to walk the entire bucket list on
each add.

Signed-off-by: Paul Moore <paul.moore@hp.com>
---

 security/selinux/netnode.c |   67 +++++++++++++++++++++-----------------------
 1 files changed, 32 insertions(+), 35 deletions(-)

diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c
index f3c526f..6d71763 100644
--- a/security/selinux/netnode.c
+++ b/security/selinux/netnode.c
@@ -40,11 +40,17 @@
 #include <net/ipv6.h>
 #include <asm/bug.h>
 
+#include "netnode.h"
 #include "objsec.h"
 
 #define SEL_NETNODE_HASH_SIZE       256
 #define SEL_NETNODE_HASH_BKT_LIMIT   16
 
+struct sel_netnode_bkt {
+	unsigned int size;
+	struct list_head list;
+};
+
 struct sel_netnode {
 	struct netnode_security_struct nsec;
 
@@ -60,7 +66,7 @@ struct sel_netnode {
 
 static LIST_HEAD(sel_netnode_list);
 static DEFINE_SPINLOCK(sel_netnode_lock);
-static struct list_head sel_netnode_hash[SEL_NETNODE_HASH_SIZE];
+static struct sel_netnode_bkt sel_netnode_hash[SEL_NETNODE_HASH_SIZE];
 
 /**
  * sel_netnode_free - Frees a node entry
@@ -87,7 +93,7 @@ static void sel_netnode_free(struct rcu_head *p)
  * the bucket number for the given IP address.
  *
  */
-static u32 sel_netnode_hashfn_ipv4(__be32 addr)
+static unsigned int sel_netnode_hashfn_ipv4(__be32 addr)
 {
 	/* at some point we should determine if the mismatch in byte order
 	 * affects the hash function dramatically */
@@ -103,7 +109,7 @@ static u32 sel_netnode_hashfn_ipv4(__be32 addr)
  * the bucket number for the given IP address.
  *
  */
-static u32 sel_netnode_hashfn_ipv6(const struct in6_addr *addr)
+static unsigned int sel_netnode_hashfn_ipv6(const struct in6_addr *addr)
 {
 	/* just hash the least significant 32 bits to keep things fast (they
 	 * are the most likely to be different anyway), we can revisit this
@@ -123,7 +129,7 @@ static u32 sel_netnode_hashfn_ipv6(const struct in6_addr *addr)
  */
 static struct sel_netnode *sel_netnode_find(const void *addr, u16 family)
 {
-	u32 idx;
+	unsigned int idx;
 	struct sel_netnode *node;
 
 	switch (family) {
@@ -137,7 +143,7 @@ static struct sel_netnode *sel_netnode_find(const void *addr, u16 family)
 		BUG();
 	}
 
-	list_for_each_entry_rcu(node, &sel_netnode_hash[idx], list)
+	list_for_each_entry_rcu(node, &sel_netnode_hash[idx].list, list)
 		if (node->nsec.family == family)
 			switch (family) {
 			case PF_INET:
@@ -165,9 +171,7 @@ static struct sel_netnode *sel_netnode_find(const void *addr, u16 family)
  */
 static int sel_netnode_insert(struct sel_netnode *node)
 {
-	u32 idx;
-	u32 count = 0;
-	struct sel_netnode *iter;
+	unsigned int idx;
 
 	switch (node->nsec.family) {
 	case PF_INET:
@@ -179,35 +183,22 @@ static int sel_netnode_insert(struct sel_netnode *node)
 	default:
 		BUG();
 	}
-	list_add_rcu(&node->list, &sel_netnode_hash[idx]);
 
 	/* we need to impose a limit on the growth of the hash table so check
 	 * this bucket to make sure it is within the specified bounds */
-	list_for_each_entry(iter, &sel_netnode_hash[idx], list)
-		if (++count > SEL_NETNODE_HASH_BKT_LIMIT) {
-			list_del_rcu(&iter->list);
-			call_rcu(&iter->rcu, sel_netnode_free);
-			break;
-		}
+	list_add_rcu(&node->list, &sel_netnode_hash[idx].list);
+	if (sel_netnode_hash[idx].size == SEL_NETNODE_HASH_BKT_LIMIT) {
+		struct sel_netnode *tail;
+		tail = list_entry(node->list.prev, struct sel_netnode, list);
+		list_del_rcu(node->list.prev);
+		call_rcu(&tail->rcu, sel_netnode_free);
+	} else
+		sel_netnode_hash[idx].size++;
 
 	return 0;
 }
 
 /**
- * sel_netnode_destroy - Remove a node record from the table
- * @node: the existing node record
- *
- * Description:
- * Remove an existing node record from the network address table.
- *
- */
-static void sel_netnode_destroy(struct sel_netnode *node)
-{
-	list_del_rcu(&node->list);
-	call_rcu(&node->rcu, sel_netnode_free);
-}
-
-/**
  * sel_netnode_sid_slow - Lookup the SID of a network address using the policy
  * @addr: the IP address
  * @family: the address family
@@ -312,13 +303,17 @@ int sel_netnode_sid(void *addr, u16 family, u32 *sid)
  */
 static void sel_netnode_flush(void)
 {
-	u32 idx;
+	unsigned int idx;
 	struct sel_netnode *node;
 
 	spin_lock_bh(&sel_netnode_lock);
-	for (idx = 0; idx < SEL_NETNODE_HASH_SIZE; idx++)
-		list_for_each_entry(node, &sel_netnode_hash[idx], list)
-			sel_netnode_destroy(node);
+	for (idx = 0; idx < SEL_NETNODE_HASH_SIZE; idx++) {
+		list_for_each_entry(node, &sel_netnode_hash[idx].list, list) {
+			list_del_rcu(&node->list);
+			call_rcu(&node->rcu, sel_netnode_free);
+		}
+		sel_netnode_hash[idx].size = 0;
+	}
 	spin_unlock_bh(&sel_netnode_lock);
 }
 
@@ -340,8 +335,10 @@ static __init int sel_netnode_init(void)
 	if (!selinux_enabled)
 		return 0;
 
-	for (iter = 0; iter < SEL_NETNODE_HASH_SIZE; iter++)
-		INIT_LIST_HEAD(&sel_netnode_hash[iter]);
+	for (iter = 0; iter < SEL_NETNODE_HASH_SIZE; iter++) {
+		INIT_LIST_HEAD(&sel_netnode_hash[iter].list);
+		sel_netnode_hash[iter].size = 0;
+	}
 
 	ret = avc_add_callback(sel_netnode_avc_callback, AVC_CALLBACK_RESET,
 	                       SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0);


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v3 2/2] SELinux: Add network port SID cache
  2008-04-10 14:48 [PATCH v3 0/2] Series short description Paul Moore
  2008-04-10 14:48 ` [PATCH v3 1/2] SELinux: Made netnode cache adds faster Paul Moore
@ 2008-04-10 14:48 ` Paul Moore
  2008-04-11 18:28   ` Stephen Smalley
  1 sibling, 1 reply; 8+ messages in thread
From: Paul Moore @ 2008-04-10 14:48 UTC (permalink / raw
  To: selinux

Much like we added a network node cache, this patch adds a network port cache.
The design is taken almost completely from the network node cache which in
turn was taken from the network interface cache.  The basic idea is to cache
entries in a hash table based on protocol/port information.  The hash
function only takes the port number into account since the number of different
protocols in use at any one time is expected to be relatively small.

Signed-off-by: Paul Moore <paul.moore@hp.com>
---

 security/selinux/Makefile           |    1 
 security/selinux/hooks.c            |   20 +-
 security/selinux/include/netport.h  |   31 ++++
 security/selinux/include/objsec.h   |    6 +
 security/selinux/include/security.h |    3 
 security/selinux/netport.c          |  286 +++++++++++++++++++++++++++++++++++
 security/selinux/ss/services.c      |    8 -
 7 files changed, 334 insertions(+), 21 deletions(-)

diff --git a/security/selinux/Makefile b/security/selinux/Makefile
index 00afd85..d47fc5e 100644
--- a/security/selinux/Makefile
+++ b/security/selinux/Makefile
@@ -11,6 +11,7 @@ selinux-y := avc.o \
 	     nlmsgtab.o \
 	     netif.o \
 	     netnode.o \
+	     netport.o \
 	     exports.o
 
 selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 820d07a..415269f 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -80,6 +80,7 @@
 #include "objsec.h"
 #include "netif.h"
 #include "netnode.h"
+#include "netport.h"
 #include "xfrm.h"
 #include "netlabel.h"
 
@@ -3626,10 +3627,8 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
 			inet_get_local_port_range(&low, &high);
 
 			if (snum < max(PROT_SOCK, low) || snum > high) {
-				err = security_port_sid(sk->sk_family,
-							sk->sk_type,
-							sk->sk_protocol, snum,
-							&sid);
+				err = sel_netport_sid(sk->sk_protocol,
+						      snum, &sid);
 				if (err)
 					goto out;
 				AVC_AUDIT_DATA_INIT(&ad,NET);
@@ -3717,8 +3716,7 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
 			snum = ntohs(addr6->sin6_port);
 		}
 
-		err = security_port_sid(sk->sk_family, sk->sk_type,
-					sk->sk_protocol, snum, &sid);
+		err = sel_netport_sid(sk->sk_protocol, snum, &sid);
 		if (err)
 			goto out;
 
@@ -3949,9 +3947,8 @@ static int selinux_sock_rcv_skb_iptables_compat(struct sock *sk,
 
 	if (!recv_perm)
 		return 0;
-	err = security_port_sid(sk->sk_family, sk->sk_type,
-				sk->sk_protocol, ntohs(ad->u.net.sport),
-				&port_sid);
+	err = sel_netport_sid(sk->sk_protocol,
+			      ntohs(ad->u.net.sport), &port_sid);
 	if (unlikely(err)) {
 		printk(KERN_WARNING
 		       "SELinux: failure in"
@@ -4372,9 +4369,8 @@ static int selinux_ip_postroute_iptables_compat(struct sock *sk,
 	if (send_perm != 0)
 		return 0;
 
-	err = security_port_sid(sk->sk_family, sk->sk_type,
-				sk->sk_protocol, ntohs(ad->u.net.dport),
-				&port_sid);
+	err = sel_netport_sid(sk->sk_protocol,
+			      ntohs(ad->u.net.dport), &port_sid);
 	if (unlikely(err)) {
 		printk(KERN_WARNING
 		       "SELinux: failure in"
diff --git a/security/selinux/include/netport.h b/security/selinux/include/netport.h
new file mode 100644
index 0000000..8991752
--- /dev/null
+++ b/security/selinux/include/netport.h
@@ -0,0 +1,31 @@
+/*
+ * Network port table
+ *
+ * SELinux must keep a mapping of network ports to labels/SIDs.  This
+ * mapping is maintained as part of the normal policy but a fast cache is
+ * needed to reduce the lookup overhead.
+ *
+ * Author: Paul Moore <paul.moore@hp.com>
+ *
+ */
+
+/*
+ * (c) Copyright Hewlett-Packard Development Company, L.P., 2008
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _SELINUX_NETPORT_H
+#define _SELINUX_NETPORT_H
+
+int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid);
+
+#endif
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index c6c2bb4..04dfdfe 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -109,6 +109,12 @@ struct netnode_security_struct {
 	u16 family;			/* address family */
 };
 
+struct netport_security_struct {
+	u32 sid;			/* SID for this node */
+	u16 port;			/* port number */
+	u8 protocol;			/* transport protocol */
+};
+
 struct sk_security_struct {
 	struct sock *sk;		/* back pointer to sk object */
 	u32 sid;			/* SID of this object */
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index f7d2f03..9901d9d 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -91,8 +91,7 @@ int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *out_s
 int security_get_user_sids(u32 callsid, char *username,
 			   u32 **sids, u32 *nel);
 
-int security_port_sid(u16 domain, u16 type, u8 protocol, u16 port,
-	u32 *out_sid);
+int security_port_sid(u8 protocol, u16 port, u32 *out_sid);
 
 int security_netif_sid(char *name, u32 *if_sid);
 
diff --git a/security/selinux/netport.c b/security/selinux/netport.c
new file mode 100644
index 0000000..68ede3c
--- /dev/null
+++ b/security/selinux/netport.c
@@ -0,0 +1,286 @@
+/*
+ * Network port table
+ *
+ * SELinux must keep a mapping of network ports to labels/SIDs.  This
+ * mapping is maintained as part of the normal policy but a fast cache is
+ * needed to reduce the lookup overhead.
+ *
+ * Author: Paul Moore <paul.moore@hp.com>
+ *
+ * This code is heavily based on the "netif" concept originally developed by
+ * James Morris <jmorris@redhat.com>
+ *   (see security/selinux/netif.c for more information)
+ *
+ */
+
+/*
+ * (c) Copyright Hewlett-Packard Development Company, L.P., 2008
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/rcupdate.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <net/ip.h>
+#include <net/ipv6.h>
+#include <asm/bug.h>
+
+#include "netport.h"
+#include "objsec.h"
+
+#define SEL_NETPORT_HASH_SIZE       256
+#define SEL_NETPORT_HASH_BKT_LIMIT   16
+
+struct sel_netport_bkt {
+	int size;
+	struct list_head list;
+};
+
+struct sel_netport {
+	struct netport_security_struct psec;
+
+	struct list_head list;
+	struct rcu_head rcu;
+};
+
+/* NOTE: we are using a combined hash table for both IPv4 and IPv6, the reason
+ * for this is that I suspect most users will not make heavy use of both
+ * address families at the same time so one table will usually end up wasted,
+ * if this becomes a problem we can always add a hash table for each address
+ * family later */
+
+static LIST_HEAD(sel_netport_list);
+static DEFINE_SPINLOCK(sel_netport_lock);
+static struct sel_netport_bkt sel_netport_hash[SEL_NETPORT_HASH_SIZE];
+
+/**
+ * sel_netport_free - Frees a port entry
+ * @p: the entry's RCU field
+ *
+ * Description:
+ * This function is designed to be used as a callback to the call_rcu()
+ * function so that memory allocated to a hash table port entry can be
+ * released safely.
+ *
+ */
+static void sel_netport_free(struct rcu_head *p)
+{
+	struct sel_netport *port = container_of(p, struct sel_netport, rcu);
+	kfree(port);
+}
+
+/**
+ * sel_netport_hashfn - Hashing function for the port table
+ * @pnum: port number
+ *
+ * Description:
+ * This is the hashing function for the port table, it returns the bucket
+ * number for the given port.
+ *
+ */
+static unsigned int sel_netport_hashfn(u16 pnum)
+{
+	return (pnum & (SEL_NETPORT_HASH_SIZE - 1));
+}
+
+/**
+ * sel_netport_find - Search for a port record
+ * @protocol: protocol
+ * @port: pnum
+ *
+ * Description:
+ * Search the network port table and return the matching record.  If an entry
+ * can not be found in the table return NULL.
+ *
+ */
+static struct sel_netport *sel_netport_find(u8 protocol, u16 pnum)
+{
+	unsigned int idx;
+	struct sel_netport *port;
+
+	idx = sel_netport_hashfn(pnum);
+	list_for_each_entry_rcu(port, &sel_netport_hash[idx].list, list)
+		if (port->psec.port == pnum &&
+		    port->psec.protocol == protocol)
+			return port;
+
+	return NULL;
+}
+
+/**
+ * sel_netport_insert - Insert a new port into the table
+ * @port: the new port record
+ *
+ * Description:
+ * Add a new port record to the network address hash table.  Returns zero on
+ * success, negative values on failure.
+ *
+ */
+static int sel_netport_insert(struct sel_netport *port)
+{
+	unsigned int idx;
+
+	/* we need to impose a limit on the growth of the hash table so check
+	 * this bucket to make sure it is within the specified bounds */
+	idx = sel_netport_hashfn(port->psec.port);
+	list_add_rcu(&port->list, &sel_netport_hash[idx].list);
+	if (sel_netport_hash[idx].size == SEL_NETPORT_HASH_BKT_LIMIT) {
+		struct sel_netport *tail;
+		tail = list_entry(port->list.prev, struct sel_netport, list);
+		list_del_rcu(port->list.prev);
+		call_rcu(&tail->rcu, sel_netport_free);
+	} else
+		sel_netport_hash[idx].size++;
+
+	return 0;
+}
+
+/**
+ * sel_netport_sid_slow - Lookup the SID of a network address using the policy
+ * @protocol: protocol
+ * @pnum: port
+ * @sid: port SID
+ *
+ * Description:
+ * This function determines the SID of a network port by quering the security
+ * policy.  The result is added to the network port table to speedup future
+ * queries.  Returns zero on success, negative values on failure.
+ *
+ */
+static int sel_netport_sid_slow(u8 protocol, u16 pnum, u32 *sid)
+{
+	int ret;
+	struct sel_netport *port;
+	struct sel_netport *new = NULL;
+
+	spin_lock_bh(&sel_netport_lock);
+	port = sel_netport_find(protocol, pnum);
+	if (port != NULL) {
+		*sid = port->psec.sid;
+		ret = 0;
+		goto out;
+	}
+	new = kzalloc(sizeof(*new), GFP_ATOMIC);
+	if (new == NULL) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	ret = security_port_sid(protocol, pnum, &new->psec.sid);
+	if (ret != 0)
+		goto out;
+	new->psec.port = pnum;
+	new->psec.protocol = protocol;
+	ret = sel_netport_insert(new);
+	if (ret != 0)
+		goto out;
+	*sid = new->psec.sid;
+
+out:
+	spin_unlock_bh(&sel_netport_lock);
+	if (unlikely(ret)) {
+		printk(KERN_WARNING
+		       "SELinux: failure in sel_netport_sid_slow(),"
+		       " unable to determine network port label\n");
+		kfree(new);
+	}
+	return ret;
+}
+
+/**
+ * sel_netport_sid - Lookup the SID of a network port
+ * @protocol: protocol
+ * @pnum: port
+ * @sid: port SID
+ *
+ * Description:
+ * This function determines the SID of a network port using the fastest method
+ * possible.  First the port table is queried, but if an entry can't be found
+ * then the policy is queried and the result is added to the table to speedup
+ * future queries.  Returns zero on success, negative values on failure.
+ *
+ */
+int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid)
+{
+	struct sel_netport *port;
+
+	rcu_read_lock();
+	port = sel_netport_find(protocol, pnum);
+	if (port != NULL) {
+		*sid = port->psec.sid;
+		rcu_read_unlock();
+		return 0;
+	}
+	rcu_read_unlock();
+
+	return sel_netport_sid_slow(protocol, pnum, sid);
+}
+
+/**
+ * sel_netport_flush - Flush the entire network port table
+ *
+ * Description:
+ * Remove all entries from the network address table.
+ *
+ */
+static void sel_netport_flush(void)
+{
+	unsigned int idx;
+	struct sel_netport *port;
+
+	spin_lock_bh(&sel_netport_lock);
+	for (idx = 0; idx < SEL_NETPORT_HASH_SIZE; idx++) {
+		list_for_each_entry(port, &sel_netport_hash[idx].list, list) {
+			list_del_rcu(&port->list);
+			call_rcu(&port->rcu, sel_netport_free);
+		}
+		sel_netport_hash[idx].size = 0;
+	}
+	spin_unlock_bh(&sel_netport_lock);
+}
+
+static int sel_netport_avc_callback(u32 event, u32 ssid, u32 tsid,
+				    u16 class, u32 perms, u32 *retained)
+{
+	if (event == AVC_CALLBACK_RESET) {
+		sel_netport_flush();
+		synchronize_net();
+	}
+	return 0;
+}
+
+static __init int sel_netport_init(void)
+{
+	int iter;
+	int ret;
+
+	if (!selinux_enabled)
+		return 0;
+
+	for (iter = 0; iter < SEL_NETPORT_HASH_SIZE; iter++) {
+		INIT_LIST_HEAD(&sel_netport_hash[iter].list);
+		sel_netport_hash[iter].size = 0;
+	}
+
+	ret = avc_add_callback(sel_netport_avc_callback, AVC_CALLBACK_RESET,
+	                       SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0);
+	if (ret != 0)
+		panic("avc_add_callback() failed, error %d\n", ret);
+
+	return ret;
+}
+
+__initcall(sel_netport_init);
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index f374186..5e499f9 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1441,17 +1441,11 @@ err:
 
 /**
  * security_port_sid - Obtain the SID for a port.
- * @domain: communication domain aka address family
- * @type: socket type
  * @protocol: protocol number
  * @port: port number
  * @out_sid: security identifier
  */
-int security_port_sid(u16 domain,
-		      u16 type,
-		      u8 protocol,
-		      u16 port,
-		      u32 *out_sid)
+int security_port_sid(u8 protocol, u16 port, u32 *out_sid)
 {
 	struct ocontext *c;
 	int rc = 0;


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 1/2] SELinux: Made netnode cache adds faster
  2008-04-10 14:48 ` [PATCH v3 1/2] SELinux: Made netnode cache adds faster Paul Moore
@ 2008-04-11 18:23   ` Stephen Smalley
  2008-04-13 23:51     ` James Morris
  0 siblings, 1 reply; 8+ messages in thread
From: Stephen Smalley @ 2008-04-11 18:23 UTC (permalink / raw
  To: Paul Moore; +Cc: selinux


On Thu, 2008-04-10 at 10:48 -0400, Paul Moore wrote:
> When adding new entries to the network node cache we would walk the entire
> hash bucket to make sure we didn't cross a threshold (done to bound the cache
> size).  This isn't a very quick or elegant solution for something which is
> supposed to be quick-ish so add a counter to each hash bucket to track the
> size of the bucket and eliminate the need to walk the entire bucket list on
> each add.
> 
> Signed-off-by: Paul Moore <paul.moore@hp.com>

Acked-by:  Stephen Smalley <sds@tycho.nsa.gov>

> ---
> 
>  security/selinux/netnode.c |   67 +++++++++++++++++++++-----------------------
>  1 files changed, 32 insertions(+), 35 deletions(-)
> 
> diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c
> index f3c526f..6d71763 100644
> --- a/security/selinux/netnode.c
> +++ b/security/selinux/netnode.c
> @@ -40,11 +40,17 @@
>  #include <net/ipv6.h>
>  #include <asm/bug.h>
>  
> +#include "netnode.h"
>  #include "objsec.h"
>  
>  #define SEL_NETNODE_HASH_SIZE       256
>  #define SEL_NETNODE_HASH_BKT_LIMIT   16
>  
> +struct sel_netnode_bkt {
> +	unsigned int size;
> +	struct list_head list;
> +};
> +
>  struct sel_netnode {
>  	struct netnode_security_struct nsec;
>  
> @@ -60,7 +66,7 @@ struct sel_netnode {
>  
>  static LIST_HEAD(sel_netnode_list);
>  static DEFINE_SPINLOCK(sel_netnode_lock);
> -static struct list_head sel_netnode_hash[SEL_NETNODE_HASH_SIZE];
> +static struct sel_netnode_bkt sel_netnode_hash[SEL_NETNODE_HASH_SIZE];
>  
>  /**
>   * sel_netnode_free - Frees a node entry
> @@ -87,7 +93,7 @@ static void sel_netnode_free(struct rcu_head *p)
>   * the bucket number for the given IP address.
>   *
>   */
> -static u32 sel_netnode_hashfn_ipv4(__be32 addr)
> +static unsigned int sel_netnode_hashfn_ipv4(__be32 addr)
>  {
>  	/* at some point we should determine if the mismatch in byte order
>  	 * affects the hash function dramatically */
> @@ -103,7 +109,7 @@ static u32 sel_netnode_hashfn_ipv4(__be32 addr)
>   * the bucket number for the given IP address.
>   *
>   */
> -static u32 sel_netnode_hashfn_ipv6(const struct in6_addr *addr)
> +static unsigned int sel_netnode_hashfn_ipv6(const struct in6_addr *addr)
>  {
>  	/* just hash the least significant 32 bits to keep things fast (they
>  	 * are the most likely to be different anyway), we can revisit this
> @@ -123,7 +129,7 @@ static u32 sel_netnode_hashfn_ipv6(const struct in6_addr *addr)
>   */
>  static struct sel_netnode *sel_netnode_find(const void *addr, u16 family)
>  {
> -	u32 idx;
> +	unsigned int idx;
>  	struct sel_netnode *node;
>  
>  	switch (family) {
> @@ -137,7 +143,7 @@ static struct sel_netnode *sel_netnode_find(const void *addr, u16 family)
>  		BUG();
>  	}
>  
> -	list_for_each_entry_rcu(node, &sel_netnode_hash[idx], list)
> +	list_for_each_entry_rcu(node, &sel_netnode_hash[idx].list, list)
>  		if (node->nsec.family == family)
>  			switch (family) {
>  			case PF_INET:
> @@ -165,9 +171,7 @@ static struct sel_netnode *sel_netnode_find(const void *addr, u16 family)
>   */
>  static int sel_netnode_insert(struct sel_netnode *node)
>  {
> -	u32 idx;
> -	u32 count = 0;
> -	struct sel_netnode *iter;
> +	unsigned int idx;
>  
>  	switch (node->nsec.family) {
>  	case PF_INET:
> @@ -179,35 +183,22 @@ static int sel_netnode_insert(struct sel_netnode *node)
>  	default:
>  		BUG();
>  	}
> -	list_add_rcu(&node->list, &sel_netnode_hash[idx]);
>  
>  	/* we need to impose a limit on the growth of the hash table so check
>  	 * this bucket to make sure it is within the specified bounds */
> -	list_for_each_entry(iter, &sel_netnode_hash[idx], list)
> -		if (++count > SEL_NETNODE_HASH_BKT_LIMIT) {
> -			list_del_rcu(&iter->list);
> -			call_rcu(&iter->rcu, sel_netnode_free);
> -			break;
> -		}
> +	list_add_rcu(&node->list, &sel_netnode_hash[idx].list);
> +	if (sel_netnode_hash[idx].size == SEL_NETNODE_HASH_BKT_LIMIT) {
> +		struct sel_netnode *tail;
> +		tail = list_entry(node->list.prev, struct sel_netnode, list);
> +		list_del_rcu(node->list.prev);
> +		call_rcu(&tail->rcu, sel_netnode_free);
> +	} else
> +		sel_netnode_hash[idx].size++;
>  
>  	return 0;
>  }
>  
>  /**
> - * sel_netnode_destroy - Remove a node record from the table
> - * @node: the existing node record
> - *
> - * Description:
> - * Remove an existing node record from the network address table.
> - *
> - */
> -static void sel_netnode_destroy(struct sel_netnode *node)
> -{
> -	list_del_rcu(&node->list);
> -	call_rcu(&node->rcu, sel_netnode_free);
> -}
> -
> -/**
>   * sel_netnode_sid_slow - Lookup the SID of a network address using the policy
>   * @addr: the IP address
>   * @family: the address family
> @@ -312,13 +303,17 @@ int sel_netnode_sid(void *addr, u16 family, u32 *sid)
>   */
>  static void sel_netnode_flush(void)
>  {
> -	u32 idx;
> +	unsigned int idx;
>  	struct sel_netnode *node;
>  
>  	spin_lock_bh(&sel_netnode_lock);
> -	for (idx = 0; idx < SEL_NETNODE_HASH_SIZE; idx++)
> -		list_for_each_entry(node, &sel_netnode_hash[idx], list)
> -			sel_netnode_destroy(node);
> +	for (idx = 0; idx < SEL_NETNODE_HASH_SIZE; idx++) {
> +		list_for_each_entry(node, &sel_netnode_hash[idx].list, list) {
> +			list_del_rcu(&node->list);
> +			call_rcu(&node->rcu, sel_netnode_free);
> +		}
> +		sel_netnode_hash[idx].size = 0;
> +	}
>  	spin_unlock_bh(&sel_netnode_lock);
>  }
>  
> @@ -340,8 +335,10 @@ static __init int sel_netnode_init(void)
>  	if (!selinux_enabled)
>  		return 0;
>  
> -	for (iter = 0; iter < SEL_NETNODE_HASH_SIZE; iter++)
> -		INIT_LIST_HEAD(&sel_netnode_hash[iter]);
> +	for (iter = 0; iter < SEL_NETNODE_HASH_SIZE; iter++) {
> +		INIT_LIST_HEAD(&sel_netnode_hash[iter].list);
> +		sel_netnode_hash[iter].size = 0;
> +	}
>  
>  	ret = avc_add_callback(sel_netnode_avc_callback, AVC_CALLBACK_RESET,
>  	                       SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0);
> 
> 
> --
> This message was distributed to subscribers of the selinux mailing list.
> If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
> the words "unsubscribe selinux" without quotes as the message.
-- 
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 2/2] SELinux: Add network port SID cache
  2008-04-10 14:48 ` [PATCH v3 2/2] SELinux: Add network port SID cache Paul Moore
@ 2008-04-11 18:28   ` Stephen Smalley
  2008-04-11 19:02     ` Paul Moore
  2008-04-13 23:51     ` James Morris
  0 siblings, 2 replies; 8+ messages in thread
From: Stephen Smalley @ 2008-04-11 18:28 UTC (permalink / raw
  To: Paul Moore; +Cc: selinux


On Thu, 2008-04-10 at 10:48 -0400, Paul Moore wrote:
> Much like we added a network node cache, this patch adds a network port cache.
> The design is taken almost completely from the network node cache which in
> turn was taken from the network interface cache.  The basic idea is to cache
> entries in a hash table based on protocol/port information.  The hash
> function only takes the port number into account since the number of different
> protocols in use at any one time is expected to be relatively small.
> 
> Signed-off-by: Paul Moore <paul.moore@hp.com>

Acked-by:  Stephen Smalley <sds@tycho.nsa.gov>

Have you run any measurements with this added?
This should address:
https://bugzilla.redhat.com/show_bug.cgi?id=234531
http://marc.info/?l=linux-kernel&m=117499007102880&w=2

> ---
> 
>  security/selinux/Makefile           |    1 
>  security/selinux/hooks.c            |   20 +-
>  security/selinux/include/netport.h  |   31 ++++
>  security/selinux/include/objsec.h   |    6 +
>  security/selinux/include/security.h |    3 
>  security/selinux/netport.c          |  286 +++++++++++++++++++++++++++++++++++
>  security/selinux/ss/services.c      |    8 -
>  7 files changed, 334 insertions(+), 21 deletions(-)
> 
> diff --git a/security/selinux/Makefile b/security/selinux/Makefile
> index 00afd85..d47fc5e 100644
> --- a/security/selinux/Makefile
> +++ b/security/selinux/Makefile
> @@ -11,6 +11,7 @@ selinux-y := avc.o \
>  	     nlmsgtab.o \
>  	     netif.o \
>  	     netnode.o \
> +	     netport.o \
>  	     exports.o
>  
>  selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 820d07a..415269f 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -80,6 +80,7 @@
>  #include "objsec.h"
>  #include "netif.h"
>  #include "netnode.h"
> +#include "netport.h"
>  #include "xfrm.h"
>  #include "netlabel.h"
>  
> @@ -3626,10 +3627,8 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
>  			inet_get_local_port_range(&low, &high);
>  
>  			if (snum < max(PROT_SOCK, low) || snum > high) {
> -				err = security_port_sid(sk->sk_family,
> -							sk->sk_type,
> -							sk->sk_protocol, snum,
> -							&sid);
> +				err = sel_netport_sid(sk->sk_protocol,
> +						      snum, &sid);
>  				if (err)
>  					goto out;
>  				AVC_AUDIT_DATA_INIT(&ad,NET);
> @@ -3717,8 +3716,7 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
>  			snum = ntohs(addr6->sin6_port);
>  		}
>  
> -		err = security_port_sid(sk->sk_family, sk->sk_type,
> -					sk->sk_protocol, snum, &sid);
> +		err = sel_netport_sid(sk->sk_protocol, snum, &sid);
>  		if (err)
>  			goto out;
>  
> @@ -3949,9 +3947,8 @@ static int selinux_sock_rcv_skb_iptables_compat(struct sock *sk,
>  
>  	if (!recv_perm)
>  		return 0;
> -	err = security_port_sid(sk->sk_family, sk->sk_type,
> -				sk->sk_protocol, ntohs(ad->u.net.sport),
> -				&port_sid);
> +	err = sel_netport_sid(sk->sk_protocol,
> +			      ntohs(ad->u.net.sport), &port_sid);
>  	if (unlikely(err)) {
>  		printk(KERN_WARNING
>  		       "SELinux: failure in"
> @@ -4372,9 +4369,8 @@ static int selinux_ip_postroute_iptables_compat(struct sock *sk,
>  	if (send_perm != 0)
>  		return 0;
>  
> -	err = security_port_sid(sk->sk_family, sk->sk_type,
> -				sk->sk_protocol, ntohs(ad->u.net.dport),
> -				&port_sid);
> +	err = sel_netport_sid(sk->sk_protocol,
> +			      ntohs(ad->u.net.dport), &port_sid);
>  	if (unlikely(err)) {
>  		printk(KERN_WARNING
>  		       "SELinux: failure in"
> diff --git a/security/selinux/include/netport.h b/security/selinux/include/netport.h
> new file mode 100644
> index 0000000..8991752
> --- /dev/null
> +++ b/security/selinux/include/netport.h
> @@ -0,0 +1,31 @@
> +/*
> + * Network port table
> + *
> + * SELinux must keep a mapping of network ports to labels/SIDs.  This
> + * mapping is maintained as part of the normal policy but a fast cache is
> + * needed to reduce the lookup overhead.
> + *
> + * Author: Paul Moore <paul.moore@hp.com>
> + *
> + */
> +
> +/*
> + * (c) Copyright Hewlett-Packard Development Company, L.P., 2008
> + *
> + * This program is free software: you can redistribute it and/or modify
> + * it under the terms of version 2 of the GNU General Public License as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#ifndef _SELINUX_NETPORT_H
> +#define _SELINUX_NETPORT_H
> +
> +int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid);
> +
> +#endif
> diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
> index c6c2bb4..04dfdfe 100644
> --- a/security/selinux/include/objsec.h
> +++ b/security/selinux/include/objsec.h
> @@ -109,6 +109,12 @@ struct netnode_security_struct {
>  	u16 family;			/* address family */
>  };
>  
> +struct netport_security_struct {
> +	u32 sid;			/* SID for this node */
> +	u16 port;			/* port number */
> +	u8 protocol;			/* transport protocol */
> +};
> +
>  struct sk_security_struct {
>  	struct sock *sk;		/* back pointer to sk object */
>  	u32 sid;			/* SID of this object */
> diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
> index f7d2f03..9901d9d 100644
> --- a/security/selinux/include/security.h
> +++ b/security/selinux/include/security.h
> @@ -91,8 +91,7 @@ int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *out_s
>  int security_get_user_sids(u32 callsid, char *username,
>  			   u32 **sids, u32 *nel);
>  
> -int security_port_sid(u16 domain, u16 type, u8 protocol, u16 port,
> -	u32 *out_sid);
> +int security_port_sid(u8 protocol, u16 port, u32 *out_sid);
>  
>  int security_netif_sid(char *name, u32 *if_sid);
>  
> diff --git a/security/selinux/netport.c b/security/selinux/netport.c
> new file mode 100644
> index 0000000..68ede3c
> --- /dev/null
> +++ b/security/selinux/netport.c
> @@ -0,0 +1,286 @@
> +/*
> + * Network port table
> + *
> + * SELinux must keep a mapping of network ports to labels/SIDs.  This
> + * mapping is maintained as part of the normal policy but a fast cache is
> + * needed to reduce the lookup overhead.
> + *
> + * Author: Paul Moore <paul.moore@hp.com>
> + *
> + * This code is heavily based on the "netif" concept originally developed by
> + * James Morris <jmorris@redhat.com>
> + *   (see security/selinux/netif.c for more information)
> + *
> + */
> +
> +/*
> + * (c) Copyright Hewlett-Packard Development Company, L.P., 2008
> + *
> + * This program is free software: you can redistribute it and/or modify
> + * it under the terms of version 2 of the GNU General Public License as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#include <linux/types.h>
> +#include <linux/rcupdate.h>
> +#include <linux/list.h>
> +#include <linux/spinlock.h>
> +#include <linux/in.h>
> +#include <linux/in6.h>
> +#include <linux/ip.h>
> +#include <linux/ipv6.h>
> +#include <net/ip.h>
> +#include <net/ipv6.h>
> +#include <asm/bug.h>
> +
> +#include "netport.h"
> +#include "objsec.h"
> +
> +#define SEL_NETPORT_HASH_SIZE       256
> +#define SEL_NETPORT_HASH_BKT_LIMIT   16
> +
> +struct sel_netport_bkt {
> +	int size;
> +	struct list_head list;
> +};
> +
> +struct sel_netport {
> +	struct netport_security_struct psec;
> +
> +	struct list_head list;
> +	struct rcu_head rcu;
> +};
> +
> +/* NOTE: we are using a combined hash table for both IPv4 and IPv6, the reason
> + * for this is that I suspect most users will not make heavy use of both
> + * address families at the same time so one table will usually end up wasted,
> + * if this becomes a problem we can always add a hash table for each address
> + * family later */
> +
> +static LIST_HEAD(sel_netport_list);
> +static DEFINE_SPINLOCK(sel_netport_lock);
> +static struct sel_netport_bkt sel_netport_hash[SEL_NETPORT_HASH_SIZE];
> +
> +/**
> + * sel_netport_free - Frees a port entry
> + * @p: the entry's RCU field
> + *
> + * Description:
> + * This function is designed to be used as a callback to the call_rcu()
> + * function so that memory allocated to a hash table port entry can be
> + * released safely.
> + *
> + */
> +static void sel_netport_free(struct rcu_head *p)
> +{
> +	struct sel_netport *port = container_of(p, struct sel_netport, rcu);
> +	kfree(port);
> +}
> +
> +/**
> + * sel_netport_hashfn - Hashing function for the port table
> + * @pnum: port number
> + *
> + * Description:
> + * This is the hashing function for the port table, it returns the bucket
> + * number for the given port.
> + *
> + */
> +static unsigned int sel_netport_hashfn(u16 pnum)
> +{
> +	return (pnum & (SEL_NETPORT_HASH_SIZE - 1));
> +}
> +
> +/**
> + * sel_netport_find - Search for a port record
> + * @protocol: protocol
> + * @port: pnum
> + *
> + * Description:
> + * Search the network port table and return the matching record.  If an entry
> + * can not be found in the table return NULL.
> + *
> + */
> +static struct sel_netport *sel_netport_find(u8 protocol, u16 pnum)
> +{
> +	unsigned int idx;
> +	struct sel_netport *port;
> +
> +	idx = sel_netport_hashfn(pnum);
> +	list_for_each_entry_rcu(port, &sel_netport_hash[idx].list, list)
> +		if (port->psec.port == pnum &&
> +		    port->psec.protocol == protocol)
> +			return port;
> +
> +	return NULL;
> +}
> +
> +/**
> + * sel_netport_insert - Insert a new port into the table
> + * @port: the new port record
> + *
> + * Description:
> + * Add a new port record to the network address hash table.  Returns zero on
> + * success, negative values on failure.
> + *
> + */
> +static int sel_netport_insert(struct sel_netport *port)
> +{
> +	unsigned int idx;
> +
> +	/* we need to impose a limit on the growth of the hash table so check
> +	 * this bucket to make sure it is within the specified bounds */
> +	idx = sel_netport_hashfn(port->psec.port);
> +	list_add_rcu(&port->list, &sel_netport_hash[idx].list);
> +	if (sel_netport_hash[idx].size == SEL_NETPORT_HASH_BKT_LIMIT) {
> +		struct sel_netport *tail;
> +		tail = list_entry(port->list.prev, struct sel_netport, list);
> +		list_del_rcu(port->list.prev);
> +		call_rcu(&tail->rcu, sel_netport_free);
> +	} else
> +		sel_netport_hash[idx].size++;
> +
> +	return 0;
> +}
> +
> +/**
> + * sel_netport_sid_slow - Lookup the SID of a network address using the policy
> + * @protocol: protocol
> + * @pnum: port
> + * @sid: port SID
> + *
> + * Description:
> + * This function determines the SID of a network port by quering the security
> + * policy.  The result is added to the network port table to speedup future
> + * queries.  Returns zero on success, negative values on failure.
> + *
> + */
> +static int sel_netport_sid_slow(u8 protocol, u16 pnum, u32 *sid)
> +{
> +	int ret;
> +	struct sel_netport *port;
> +	struct sel_netport *new = NULL;
> +
> +	spin_lock_bh(&sel_netport_lock);
> +	port = sel_netport_find(protocol, pnum);
> +	if (port != NULL) {
> +		*sid = port->psec.sid;
> +		ret = 0;
> +		goto out;
> +	}
> +	new = kzalloc(sizeof(*new), GFP_ATOMIC);
> +	if (new == NULL) {
> +		ret = -ENOMEM;
> +		goto out;
> +	}
> +	ret = security_port_sid(protocol, pnum, &new->psec.sid);
> +	if (ret != 0)
> +		goto out;
> +	new->psec.port = pnum;
> +	new->psec.protocol = protocol;
> +	ret = sel_netport_insert(new);
> +	if (ret != 0)
> +		goto out;
> +	*sid = new->psec.sid;
> +
> +out:
> +	spin_unlock_bh(&sel_netport_lock);
> +	if (unlikely(ret)) {
> +		printk(KERN_WARNING
> +		       "SELinux: failure in sel_netport_sid_slow(),"
> +		       " unable to determine network port label\n");
> +		kfree(new);
> +	}
> +	return ret;
> +}
> +
> +/**
> + * sel_netport_sid - Lookup the SID of a network port
> + * @protocol: protocol
> + * @pnum: port
> + * @sid: port SID
> + *
> + * Description:
> + * This function determines the SID of a network port using the fastest method
> + * possible.  First the port table is queried, but if an entry can't be found
> + * then the policy is queried and the result is added to the table to speedup
> + * future queries.  Returns zero on success, negative values on failure.
> + *
> + */
> +int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid)
> +{
> +	struct sel_netport *port;
> +
> +	rcu_read_lock();
> +	port = sel_netport_find(protocol, pnum);
> +	if (port != NULL) {
> +		*sid = port->psec.sid;
> +		rcu_read_unlock();
> +		return 0;
> +	}
> +	rcu_read_unlock();
> +
> +	return sel_netport_sid_slow(protocol, pnum, sid);
> +}
> +
> +/**
> + * sel_netport_flush - Flush the entire network port table
> + *
> + * Description:
> + * Remove all entries from the network address table.
> + *
> + */
> +static void sel_netport_flush(void)
> +{
> +	unsigned int idx;
> +	struct sel_netport *port;
> +
> +	spin_lock_bh(&sel_netport_lock);
> +	for (idx = 0; idx < SEL_NETPORT_HASH_SIZE; idx++) {
> +		list_for_each_entry(port, &sel_netport_hash[idx].list, list) {
> +			list_del_rcu(&port->list);
> +			call_rcu(&port->rcu, sel_netport_free);
> +		}
> +		sel_netport_hash[idx].size = 0;
> +	}
> +	spin_unlock_bh(&sel_netport_lock);
> +}
> +
> +static int sel_netport_avc_callback(u32 event, u32 ssid, u32 tsid,
> +				    u16 class, u32 perms, u32 *retained)
> +{
> +	if (event == AVC_CALLBACK_RESET) {
> +		sel_netport_flush();
> +		synchronize_net();
> +	}
> +	return 0;
> +}
> +
> +static __init int sel_netport_init(void)
> +{
> +	int iter;
> +	int ret;
> +
> +	if (!selinux_enabled)
> +		return 0;
> +
> +	for (iter = 0; iter < SEL_NETPORT_HASH_SIZE; iter++) {
> +		INIT_LIST_HEAD(&sel_netport_hash[iter].list);
> +		sel_netport_hash[iter].size = 0;
> +	}
> +
> +	ret = avc_add_callback(sel_netport_avc_callback, AVC_CALLBACK_RESET,
> +	                       SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0);
> +	if (ret != 0)
> +		panic("avc_add_callback() failed, error %d\n", ret);
> +
> +	return ret;
> +}
> +
> +__initcall(sel_netport_init);
> diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
> index f374186..5e499f9 100644
> --- a/security/selinux/ss/services.c
> +++ b/security/selinux/ss/services.c
> @@ -1441,17 +1441,11 @@ err:
>  
>  /**
>   * security_port_sid - Obtain the SID for a port.
> - * @domain: communication domain aka address family
> - * @type: socket type
>   * @protocol: protocol number
>   * @port: port number
>   * @out_sid: security identifier
>   */
> -int security_port_sid(u16 domain,
> -		      u16 type,
> -		      u8 protocol,
> -		      u16 port,
> -		      u32 *out_sid)
> +int security_port_sid(u8 protocol, u16 port, u32 *out_sid)
>  {
>  	struct ocontext *c;
>  	int rc = 0;
> 
> 
> --
> This message was distributed to subscribers of the selinux mailing list.
> If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
> the words "unsubscribe selinux" without quotes as the message.
-- 
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 2/2] SELinux: Add network port SID cache
  2008-04-11 18:28   ` Stephen Smalley
@ 2008-04-11 19:02     ` Paul Moore
  2008-04-13 23:51     ` James Morris
  1 sibling, 0 replies; 8+ messages in thread
From: Paul Moore @ 2008-04-11 19:02 UTC (permalink / raw
  To: Stephen Smalley; +Cc: selinux

On Friday 11 April 2008 2:28:14 pm Stephen Smalley wrote:
> On Thu, 2008-04-10 at 10:48 -0400, Paul Moore wrote:
> > Much like we added a network node cache, this patch adds a network
> > port cache. The design is taken almost completely from the network
> > node cache which in turn was taken from the network interface
> > cache.  The basic idea is to cache entries in a hash table based on
> > protocol/port information.  The hash function only takes the port
> > number into account since the number of different protocols in use
> > at any one time is expected to be relatively small.
> >
> > Signed-off-by: Paul Moore <paul.moore@hp.com>
>
> Acked-by:  Stephen Smalley <sds@tycho.nsa.gov>
>
> Have you run any measurements with this added?

Not at present.

> This should address:
> https://bugzilla.redhat.com/show_bug.cgi?id=234531
> http://marc.info/?l=linux-kernel&m=117499007102880&w=2

Yep.

-- 
paul moore
linux @ hp

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 2/2] SELinux: Add network port SID cache
  2008-04-11 18:28   ` Stephen Smalley
  2008-04-11 19:02     ` Paul Moore
@ 2008-04-13 23:51     ` James Morris
  1 sibling, 0 replies; 8+ messages in thread
From: James Morris @ 2008-04-13 23:51 UTC (permalink / raw
  To: Stephen Smalley; +Cc: Paul Moore, selinux

On Fri, 11 Apr 2008, Stephen Smalley wrote:

> 
> On Thu, 2008-04-10 at 10:48 -0400, Paul Moore wrote:
> > Much like we added a network node cache, this patch adds a network port cache.
> > The design is taken almost completely from the network node cache which in
> > turn was taken from the network interface cache.  The basic idea is to cache
> > entries in a hash table based on protocol/port information.  The hash
> > function only takes the port number into account since the number of different
> > protocols in use at any one time is expected to be relatively small.
> > 
> > Signed-off-by: Paul Moore <paul.moore@hp.com>
> 
> Acked-by:  Stephen Smalley <sds@tycho.nsa.gov>

Applied to for-akpm.


-- 
James Morris
<jmorris@namei.org>

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 1/2] SELinux: Made netnode cache adds faster
  2008-04-11 18:23   ` Stephen Smalley
@ 2008-04-13 23:51     ` James Morris
  0 siblings, 0 replies; 8+ messages in thread
From: James Morris @ 2008-04-13 23:51 UTC (permalink / raw
  To: Stephen Smalley; +Cc: Paul Moore, selinux

On Fri, 11 Apr 2008, Stephen Smalley wrote:

> 
> On Thu, 2008-04-10 at 10:48 -0400, Paul Moore wrote:
> > When adding new entries to the network node cache we would walk the entire
> > hash bucket to make sure we didn't cross a threshold (done to bound the cache
> > size).  This isn't a very quick or elegant solution for something which is
> > supposed to be quick-ish so add a counter to each hash bucket to track the
> > size of the bucket and eliminate the need to walk the entire bucket list on
> > each add.
> > 
> > Signed-off-by: Paul Moore <paul.moore@hp.com>
> 
> Acked-by:  Stephen Smalley <sds@tycho.nsa.gov>

Applied to for-akpm.


-- 
James Morris
<jmorris@namei.org>

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2008-04-13 23:51 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-10 14:48 [PATCH v3 0/2] Series short description Paul Moore
2008-04-10 14:48 ` [PATCH v3 1/2] SELinux: Made netnode cache adds faster Paul Moore
2008-04-11 18:23   ` Stephen Smalley
2008-04-13 23:51     ` James Morris
2008-04-10 14:48 ` [PATCH v3 2/2] SELinux: Add network port SID cache Paul Moore
2008-04-11 18:28   ` Stephen Smalley
2008-04-11 19:02     ` Paul Moore
2008-04-13 23:51     ` James Morris

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.