diff options
author | Eric Dumazet <edumazet@google.com> | 2016-06-02 17:52:43 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-06-02 18:29:49 -0400 |
commit | ce25d66ad5f8d921bac5fe2d32d62fa30c0f9a70 (patch) | |
tree | b1645065bc25d86d42c902de87cc548fe7fddf8f /net | |
parent | f55d84b07c4e7340473a25dc82b462607578402c (diff) |
Possible problem with e6afc8ac ("udp: remove headers from UDP packets before queueing")
Paul Moore tracked a regression caused by a recent commit, which
mistakenly assumed that sk_filter() could be avoided if socket
had no current BPF filter.
The intent was to avoid udp_lib_checksum_complete() overhead.
But sk_filter() also checks skb_pfmemalloc() and
security_sock_rcv_skb(), so better call it.
Fixes: e6afc8ace6dd ("udp: remove headers from UDP packets before queueing")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: Paul Moore <paul@paul-moore.com>
Tested-by: Paul Moore <paul@paul-moore.com>
Tested-by: Stephen Smalley <sds@tycho.nsa.gov>
Cc: samanthakumar <samanthakumar@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/udp.c | 10 | ||||
-rw-r--r-- | net/ipv6/udp.c | 12 |
2 files changed, 11 insertions, 11 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index d56c0559b477..0ff31d97d485 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -1618,12 +1618,12 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
1618 | } | 1618 | } |
1619 | } | 1619 | } |
1620 | 1620 | ||
1621 | if (rcu_access_pointer(sk->sk_filter)) { | 1621 | if (rcu_access_pointer(sk->sk_filter) && |
1622 | if (udp_lib_checksum_complete(skb)) | 1622 | udp_lib_checksum_complete(skb)) |
1623 | goto csum_error; | 1623 | goto csum_error; |
1624 | if (sk_filter(sk, skb)) | 1624 | |
1625 | goto drop; | 1625 | if (sk_filter(sk, skb)) |
1626 | } | 1626 | goto drop; |
1627 | 1627 | ||
1628 | udp_csum_pull_header(skb); | 1628 | udp_csum_pull_header(skb); |
1629 | if (sk_rcvqueues_full(sk, sk->sk_rcvbuf)) { | 1629 | if (sk_rcvqueues_full(sk, sk->sk_rcvbuf)) { |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 2da1896af934..f421c9f23c5b 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -653,12 +653,12 @@ int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
653 | } | 653 | } |
654 | } | 654 | } |
655 | 655 | ||
656 | if (rcu_access_pointer(sk->sk_filter)) { | 656 | if (rcu_access_pointer(sk->sk_filter) && |
657 | if (udp_lib_checksum_complete(skb)) | 657 | udp_lib_checksum_complete(skb)) |
658 | goto csum_error; | 658 | goto csum_error; |
659 | if (sk_filter(sk, skb)) | 659 | |
660 | goto drop; | 660 | if (sk_filter(sk, skb)) |
661 | } | 661 | goto drop; |
662 | 662 | ||
663 | udp_csum_pull_header(skb); | 663 | udp_csum_pull_header(skb); |
664 | if (sk_rcvqueues_full(sk, sk->sk_rcvbuf)) { | 664 | if (sk_rcvqueues_full(sk, sk->sk_rcvbuf)) { |