Skip to content

Commit ca10b9e

Browse files
edumazetdavem330
authored andcommitted
selinux: add a skb_owned_by() hook
Commit 90ba9b1 (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>
1 parent c802d75 commit ca10b9e

File tree

5 files changed

+27
-0
lines changed

5 files changed

+27
-0
lines changed

include/linux/security.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1638,6 +1638,7 @@ struct security_operations {
16381638
int (*tun_dev_attach_queue) (void *security);
16391639
int (*tun_dev_attach) (struct sock *sk, void *security);
16401640
int (*tun_dev_open) (void *security);
1641+
void (*skb_owned_by) (struct sk_buff *skb, struct sock *sk);
16411642
#endif /* CONFIG_SECURITY_NETWORK */
16421643

16431644
#ifdef CONFIG_SECURITY_NETWORK_XFRM
@@ -2588,6 +2589,8 @@ int security_tun_dev_attach_queue(void *security);
25882589
int security_tun_dev_attach(struct sock *sk, void *security);
25892590
int security_tun_dev_open(void *security);
25902591

2592+
void security_skb_owned_by(struct sk_buff *skb, struct sock *sk);
2593+
25912594
#else /* CONFIG_SECURITY_NETWORK */
25922595
static inline int security_unix_stream_connect(struct sock *sock,
25932596
struct sock *other,
@@ -2779,6 +2782,11 @@ static inline int security_tun_dev_open(void *security)
27792782
{
27802783
return 0;
27812784
}
2785+
2786+
static inline void security_skb_owned_by(struct sk_buff *skb, struct sock *sk)
2787+
{
2788+
}
2789+
27822790
#endif /* CONFIG_SECURITY_NETWORK */
27832791

27842792
#ifdef CONFIG_SECURITY_NETWORK_XFRM

net/ipv4/tcp_output.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2709,6 +2709,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
27092709
skb_reserve(skb, MAX_TCP_HEADER);
27102710

27112711
skb_dst_set(skb, dst);
2712+
security_skb_owned_by(skb, sk);
27122713

27132714
mss = dst_metric_advmss(dst);
27142715
if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < mss)

security/capability.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,11 @@ static int cap_tun_dev_open(void *security)
737737
{
738738
return 0;
739739
}
740+
741+
static void cap_skb_owned_by(struct sk_buff *skb, struct sock *sk)
742+
{
743+
}
744+
740745
#endif /* CONFIG_SECURITY_NETWORK */
741746

742747
#ifdef CONFIG_SECURITY_NETWORK_XFRM
@@ -1071,6 +1076,7 @@ void __init security_fixup_ops(struct security_operations *ops)
10711076
set_to_cap_if_null(ops, tun_dev_open);
10721077
set_to_cap_if_null(ops, tun_dev_attach_queue);
10731078
set_to_cap_if_null(ops, tun_dev_attach);
1079+
set_to_cap_if_null(ops, skb_owned_by);
10741080
#endif /* CONFIG_SECURITY_NETWORK */
10751081
#ifdef CONFIG_SECURITY_NETWORK_XFRM
10761082
set_to_cap_if_null(ops, xfrm_policy_alloc_security);

security/security.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,6 +1290,11 @@ int security_tun_dev_open(void *security)
12901290
}
12911291
EXPORT_SYMBOL(security_tun_dev_open);
12921292

1293+
void security_skb_owned_by(struct sk_buff *skb, struct sock *sk)
1294+
{
1295+
security_ops->skb_owned_by(skb, sk);
1296+
}
1297+
12931298
#endif /* CONFIG_SECURITY_NETWORK */
12941299

12951300
#ifdef CONFIG_SECURITY_NETWORK_XFRM

security/selinux/hooks.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#include <linux/tty.h>
5252
#include <net/icmp.h>
5353
#include <net/ip.h> /* for local_port_range[] */
54+
#include <net/sock.h>
5455
#include <net/tcp.h> /* struct or_callable used in sock_rcv_skb */
5556
#include <net/net_namespace.h>
5657
#include <net/netlabel.h>
@@ -4363,6 +4364,11 @@ static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb)
43634364
selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid);
43644365
}
43654366

4367+
static void selinux_skb_owned_by(struct sk_buff *skb, struct sock *sk)
4368+
{
4369+
skb_set_owner_w(skb, sk);
4370+
}
4371+
43664372
static int selinux_secmark_relabel_packet(u32 sid)
43674373
{
43684374
const struct task_security_struct *__tsec;
@@ -5664,6 +5670,7 @@ static struct security_operations selinux_ops = {
56645670
.tun_dev_attach_queue = selinux_tun_dev_attach_queue,
56655671
.tun_dev_attach = selinux_tun_dev_attach,
56665672
.tun_dev_open = selinux_tun_dev_open,
5673+
.skb_owned_by = selinux_skb_owned_by,
56675674

56685675
#ifdef CONFIG_SECURITY_NETWORK_XFRM
56695676
.xfrm_policy_alloc_security = selinux_xfrm_policy_alloc,

0 commit comments

Comments
 (0)