SELinux: Add a network node caching mechanism similar to the sel_netif_*() functions
This patch adds a SELinux IP address/node SID caching mechanism similar to the
sel_netif_*() functions. The node SID queries in the SELinux hooks files are
also modified to take advantage of this new functionality. In addition, remove
the address length information from the sk_buff parsing routines as it is
redundant since we already have the address family.
Signed-off-by: Paul Moore <paul.moore@hp.com>
Signed-off-by: James Morris <jmorris@namei.org>
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 1a1fa3f..4bca0af 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -76,6 +76,7 @@
#include "avc.h"
#include "objsec.h"
#include "netif.h"
+#include "netnode.h"
#include "xfrm.h"
#include "netlabel.h"
@@ -3395,7 +3396,7 @@
#endif /* IPV6 */
static int selinux_parse_skb(struct sk_buff *skb, struct avc_audit_data *ad,
- char **addrp, int *len, int src, u8 *proto)
+ char **addrp, int src, u8 *proto)
{
int ret = 0;
@@ -3404,7 +3405,6 @@
ret = selinux_parse_skb_ipv4(skb, ad, proto);
if (ret || !addrp)
break;
- *len = 4;
*addrp = (char *)(src ? &ad->u.net.v4info.saddr :
&ad->u.net.v4info.daddr);
break;
@@ -3414,7 +3414,6 @@
ret = selinux_parse_skb_ipv6(skb, ad, proto);
if (ret || !addrp)
break;
- *len = 16;
*addrp = (char *)(src ? &ad->u.net.v6info.saddr :
&ad->u.net.v6info.daddr);
break;
@@ -3614,7 +3613,7 @@
break;
}
- err = security_node_sid(family, addrp, addrlen, &sid);
+ err = sel_netnode_sid(addrp, family, &sid);
if (err)
goto out;
@@ -3826,7 +3825,8 @@
}
static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
- struct avc_audit_data *ad, u16 family, char *addrp, int len)
+ struct avc_audit_data *ad,
+ u16 family, char *addrp)
{
int err = 0;
u32 netif_perm, node_perm, node_sid, if_sid, recv_perm = 0;
@@ -3886,7 +3886,7 @@
if (err)
goto out;
- err = security_node_sid(family, addrp, len, &node_sid);
+ err = sel_netnode_sid(addrp, family, &node_sid);
if (err)
goto out;
@@ -3915,7 +3915,7 @@
{
u16 family;
char *addrp;
- int len, err = 0;
+ int err = 0;
struct avc_audit_data ad;
struct sk_security_struct *sksec = sk->sk_security;
@@ -3931,13 +3931,12 @@
ad.u.net.netif = skb->iif;
ad.u.net.family = family;
- err = selinux_parse_skb(skb, &ad, &addrp, &len, 1, NULL);
+ err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
if (err)
goto out;
if (selinux_compat_net)
- err = selinux_sock_rcv_skb_compat(sk, skb, &ad, family,
- addrp, len);
+ err = selinux_sock_rcv_skb_compat(sk, skb, &ad, family, addrp);
else
err = avc_has_perm(sksec->sid, skb->secmark, SECCLASS_PACKET,
PACKET__RECV, &ad);
@@ -4158,9 +4157,11 @@
#ifdef CONFIG_NETFILTER
-static int selinux_ip_postroute_last_compat(struct sock *sk, struct net_device *dev,
+static int selinux_ip_postroute_last_compat(struct sock *sk,
+ struct net_device *dev,
struct avc_audit_data *ad,
- u16 family, char *addrp, int len)
+ u16 family,
+ char *addrp)
{
int err = 0;
u32 netif_perm, node_perm, node_sid, if_sid, send_perm = 0;
@@ -4211,7 +4212,7 @@
if (err)
goto out;
- err = security_node_sid(family, addrp, len, &node_sid);
+ err = sel_netnode_sid(addrp, family, &node_sid);
if (err)
goto out;
@@ -4245,7 +4246,7 @@
u16 family)
{
char *addrp;
- int len, err = 0;
+ int err = 0;
struct sock *sk;
struct avc_audit_data ad;
struct net_device *dev = (struct net_device *)out;
@@ -4262,13 +4263,13 @@
ad.u.net.netif = dev->ifindex;
ad.u.net.family = family;
- err = selinux_parse_skb(skb, &ad, &addrp, &len, 0, &proto);
+ err = selinux_parse_skb(skb, &ad, &addrp, 0, &proto);
if (err)
goto out;
if (selinux_compat_net)
err = selinux_ip_postroute_last_compat(sk, dev, &ad,
- family, addrp, len);
+ family, addrp);
else
err = avc_has_perm(sksec->sid, skb->secmark, SECCLASS_PACKET,
PACKET__SEND, &ad);