aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2013-04-08 13:58:11 -0400
committerDavid S. Miller <davem@davemloft.net>2013-04-09 13:23:11 -0400
commitca10b9e9a8ca7342ee07065289cbe74ac128c169 (patch)
tree33842f41a127f9da904ddd5d61839590e986e420 /security
parentc802d759623acbd6e1ee9fbdabae89159a513913 (diff)
selinux: add a skb_owned_by() hook
Commit 90ba9b1986b5ac (tcp: tcp_make_synack() can use alloc_skb()) broke certain SELinux/NetLabel configurations by no longer correctly assigning the sock to the outgoing SYNACK packet. Cost of atomic operations on the LISTEN socket is quite big, and we would like it to happen only if really needed. This patch introduces a new security_ops->skb_owned_by() method, that is a void operation unless selinux is active. Reported-by: Miroslav Vadkerti <mvadkert@redhat.com> Diagnosed-by: Paul Moore <pmoore@redhat.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: "David S. Miller" <davem@davemloft.net> Cc: linux-security-module@vger.kernel.org Acked-by: James Morris <james.l.morris@oracle.com> Tested-by: Paul Moore <pmoore@redhat.com> Acked-by: Paul Moore <pmoore@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'security')
-rw-r--r--security/capability.c6
-rw-r--r--security/security.c5
-rw-r--r--security/selinux/hooks.c7
3 files changed, 18 insertions, 0 deletions
diff --git a/security/capability.c b/security/capability.c
index 579775088967..6783c3e6c88e 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -737,6 +737,11 @@ static int cap_tun_dev_open(void *security)
737{ 737{
738 return 0; 738 return 0;
739} 739}
740
741static void cap_skb_owned_by(struct sk_buff *skb, struct sock *sk)
742{
743}
744
740#endif /* CONFIG_SECURITY_NETWORK */ 745#endif /* CONFIG_SECURITY_NETWORK */
741 746
742#ifdef CONFIG_SECURITY_NETWORK_XFRM 747#ifdef CONFIG_SECURITY_NETWORK_XFRM
@@ -1071,6 +1076,7 @@ void __init security_fixup_ops(struct security_operations *ops)
1071 set_to_cap_if_null(ops, tun_dev_open); 1076 set_to_cap_if_null(ops, tun_dev_open);
1072 set_to_cap_if_null(ops, tun_dev_attach_queue); 1077 set_to_cap_if_null(ops, tun_dev_attach_queue);
1073 set_to_cap_if_null(ops, tun_dev_attach); 1078 set_to_cap_if_null(ops, tun_dev_attach);
1079 set_to_cap_if_null(ops, skb_owned_by);
1074#endif /* CONFIG_SECURITY_NETWORK */ 1080#endif /* CONFIG_SECURITY_NETWORK */
1075#ifdef CONFIG_SECURITY_NETWORK_XFRM 1081#ifdef CONFIG_SECURITY_NETWORK_XFRM
1076 set_to_cap_if_null(ops, xfrm_policy_alloc_security); 1082 set_to_cap_if_null(ops, xfrm_policy_alloc_security);
diff --git a/security/security.c b/security/security.c
index 7b88c6aeaed4..03f248b84e9f 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1290,6 +1290,11 @@ int security_tun_dev_open(void *security)
1290} 1290}
1291EXPORT_SYMBOL(security_tun_dev_open); 1291EXPORT_SYMBOL(security_tun_dev_open);
1292 1292
1293void security_skb_owned_by(struct sk_buff *skb, struct sock *sk)
1294{
1295 security_ops->skb_owned_by(skb, sk);
1296}
1297
1293#endif /* CONFIG_SECURITY_NETWORK */ 1298#endif /* CONFIG_SECURITY_NETWORK */
1294 1299
1295#ifdef CONFIG_SECURITY_NETWORK_XFRM 1300#ifdef CONFIG_SECURITY_NETWORK_XFRM
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 2fa28c88900c..7171a957b933 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -51,6 +51,7 @@
51#include <linux/tty.h> 51#include <linux/tty.h>
52#include <net/icmp.h> 52#include <net/icmp.h>
53#include <net/ip.h> /* for local_port_range[] */ 53#include <net/ip.h> /* for local_port_range[] */
54#include <net/sock.h>
54#include <net/tcp.h> /* struct or_callable used in sock_rcv_skb */ 55#include <net/tcp.h> /* struct or_callable used in sock_rcv_skb */
55#include <net/net_namespace.h> 56#include <net/net_namespace.h>
56#include <net/netlabel.h> 57#include <net/netlabel.h>
@@ -4363,6 +4364,11 @@ static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb)
4363 selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid); 4364 selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid);
4364} 4365}
4365 4366
4367static void selinux_skb_owned_by(struct sk_buff *skb, struct sock *sk)
4368{
4369 skb_set_owner_w(skb, sk);
4370}
4371
4366static int selinux_secmark_relabel_packet(u32 sid) 4372static int selinux_secmark_relabel_packet(u32 sid)
4367{ 4373{
4368 const struct task_security_struct *__tsec; 4374 const struct task_security_struct *__tsec;
@@ -5664,6 +5670,7 @@ static struct security_operations selinux_ops = {
5664 .tun_dev_attach_queue = selinux_tun_dev_attach_queue, 5670 .tun_dev_attach_queue = selinux_tun_dev_attach_queue,
5665 .tun_dev_attach = selinux_tun_dev_attach, 5671 .tun_dev_attach = selinux_tun_dev_attach,
5666 .tun_dev_open = selinux_tun_dev_open, 5672 .tun_dev_open = selinux_tun_dev_open,
5673 .skb_owned_by = selinux_skb_owned_by,
5667 5674
5668#ifdef CONFIG_SECURITY_NETWORK_XFRM 5675#ifdef CONFIG_SECURITY_NETWORK_XFRM
5669 .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc, 5676 .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc,