SELinux: Add network port SID cache
authorPaul Moore <paul.moore@hp.com>
Thu, 10 Apr 2008 14:48:14 +0000 (10:48 -0400)
committerJames Morris <jmorris@namei.org>
Fri, 18 Apr 2008 10:26:16 +0000 (20:26 +1000)
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>
Signed-off-by: James Morris <jmorris@namei.org>
security/selinux/Makefile
security/selinux/hooks.c
security/selinux/include/objsec.h
security/selinux/include/security.h
security/selinux/ss/services.c

index 00afd85f1edb903544ae9d3f365f0e6df7ac397b..d47fc5e545e08c873bf769fe54f90cff9c952b8d 100644 (file)
@@ -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
index 93c809a6e4fac5c1535650a2adb4d4811669c810..34f2d46c79847f8b8990cf57485a9fc308c84833 100644 (file)
@@ -80,6 +80,7 @@
 #include "objsec.h"
 #include "netif.h"
 #include "netnode.h"
+#include "netport.h"
 #include "xfrm.h"
 #include "netlabel.h"
 
@@ -3670,10 +3671,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);
@@ -3761,8 +3760,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;
 
@@ -3993,9 +3991,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"
@@ -4416,9 +4413,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"
index 957b10d0f76fd64f5f9b26f62ca2deb608132959..300b61bad7b3738cf5934b9b3e328d410361e418 100644 (file)
@@ -103,6 +103,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 {
        u32 sid;                        /* SID of this object */
        u32 peer_sid;                   /* SID of peer */
index bc823ef70a12ce848e532840ce34b0187d4ea4f6..1904c462a605fc99dd29b9107c6c797d7ed4d62d 100644 (file)
@@ -102,8 +102,7 @@ int security_context_to_sid_default(char *scontext, u32 scontext_len,
 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);
 
index 098c96b6f9deb585065fbcf99c7fb9bb8b5d7d3f..d75050819b0641c346cbbe0d4e3dbbfacbbada99 100644 (file)
@@ -1472,17 +1472,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;