diff options
author | Daniel Borkmann <dborkman@redhat.com> | 2013-12-23 14:35:55 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-12-31 14:31:43 -0500 |
commit | 73bfd370c878d3feb3c3111cc17af066dc1f455b (patch) | |
tree | 960d9bac33fcc8406831ba09e0c662fa65ef1114 /net/netlink | |
parent | 89ba52bd933898e8da78d4a3469dc23cb8acbecd (diff) | |
download | linux-73bfd370c878d3feb3c3111cc17af066dc1f455b.tar.gz linux-73bfd370c878d3feb3c3111cc17af066dc1f455b.tar.bz2 linux-73bfd370c878d3feb3c3111cc17af066dc1f455b.zip |
netlink: only do not deliver to tap when both sides are kernel sks
We should also deliver packets to nlmon devices when we are in
netlink_unicast_kernel(), and only one of the {src,dst} sockets
is user sk and the other one kernel sk. That's e.g. the case in
netlink diag, netlink route, etc. Still, forbid to deliver messages
from kernel to kernel sks.
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Signed-off-by: Jakub Zawadzki <darkjames-ws@darkjames.pl>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netlink')
-rw-r--r-- | net/netlink/af_netlink.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index bca50b95c182..56e09d8a55fd 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -239,6 +239,13 @@ static void netlink_deliver_tap(struct sk_buff *skb) rcu_read_unlock(); } +static void netlink_deliver_tap_kernel(struct sock *dst, struct sock *src, + struct sk_buff *skb) +{ + if (!(netlink_is_kernel(dst) && netlink_is_kernel(src))) + netlink_deliver_tap(skb); +} + static void netlink_overrun(struct sock *sk) { struct netlink_sock *nlk = nlk_sk(sk); @@ -1697,14 +1704,10 @@ static int netlink_unicast_kernel(struct sock *sk, struct sk_buff *skb, ret = -ECONNREFUSED; if (nlk->netlink_rcv != NULL) { - /* We could do a netlink_deliver_tap(skb) here as well - * but since this is intended for the kernel only, we - * should rather let it stay under the hood. - */ - ret = skb->len; netlink_skb_set_owner_r(skb, sk); NETLINK_CB(skb).sk = ssk; + netlink_deliver_tap_kernel(sk, ssk, skb); nlk->netlink_rcv(skb); consume_skb(skb); } else { |