diff options
author | Martin KaFai Lau <kafai@fb.com> | 2019-05-31 15:29:11 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-07-10 09:55:42 +0200 |
commit | 0f00d44f9884ca588e42f942f6a6fafbb0c0afc0 (patch) | |
tree | 73af28664ee673123727e20338e301d9b009e4cd | |
parent | 3c77e8fe4ff65ec3239c22072ff9517b2645dd13 (diff) | |
download | linux-stable-0f00d44f9884ca588e42f942f6a6fafbb0c0afc0.tar.gz linux-stable-0f00d44f9884ca588e42f942f6a6fafbb0c0afc0.tar.bz2 linux-stable-0f00d44f9884ca588e42f942f6a6fafbb0c0afc0.zip |
bpf: udp: ipv6: Avoid running reuseport's bpf_prog from __udp6_lib_err
commit 4ac30c4b3659efac031818c418beb51e630d512d upstream.
__udp6_lib_err() may be called when handling icmpv6 message. For example,
the icmpv6 toobig(type=2). __udp6_lib_lookup() is then called
which may call reuseport_select_sock(). reuseport_select_sock() will
call into a bpf_prog (if there is one).
reuseport_select_sock() is expecting the skb->data pointing to the
transport header (udphdr in this case). For example, run_bpf_filter()
is pulling the transport header.
However, in the __udp6_lib_err() path, the skb->data is pointing to the
ipv6hdr instead of the udphdr.
One option is to pull and push the ipv6hdr in __udp6_lib_err().
Instead of doing this, this patch follows how the original
commit 538950a1b752 ("soreuseport: setsockopt SO_ATTACH_REUSEPORT_[CE]BPF")
was done in IPv4, which has passed a NULL skb pointer to
reuseport_select_sock().
Fixes: 538950a1b752 ("soreuseport: setsockopt SO_ATTACH_REUSEPORT_[CE]BPF")
Cc: Craig Gallek <kraig@google.com>
Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Acked-by: Song Liu <songliubraving@fb.com>
Acked-by: Craig Gallek <kraig@google.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | net/ipv6/udp.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 48478cff9226..6a397e110b46 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -479,7 +479,7 @@ void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt, struct net *net = dev_net(skb->dev); sk = __udp6_lib_lookup(net, daddr, uh->dest, saddr, uh->source, - inet6_iif(skb), udptable, skb); + inet6_iif(skb), udptable, NULL); if (!sk) { __ICMP6_INC_STATS(net, __in6_dev_get(skb->dev), ICMP6_MIB_INERRORS); |