diff options
author | Cong Wang <cong.wang@bytedance.com> | 2021-11-15 07:40:06 +0300 |
---|---|---|
committer | Daniel Borkmann <daniel@iogearbox.net> | 2021-11-16 15:18:23 +0300 |
commit | 099f896f498a2b26d84f4ddae039b2c542c18b48 (patch) | |
tree | 0b9515284b4d457b6d265a367752a7f1ab309ce2 /net/ipv4 | |
parent | 353050be4c19e102178ccc05988101887c25ae53 (diff) | |
download | linux-099f896f498a2b26d84f4ddae039b2c542c18b48.tar.xz |
udp: Validate checksum in udp_read_sock()
It turns out the skb's in sock receive queue could have bad checksums, as
both ->poll() and ->recvmsg() validate checksums. We have to do the same
for ->read_sock() path too before they are redirected in sockmap.
Fixes: d7f571188ecf ("udp: Implement ->read_sock() for sockmap")
Reported-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Cong Wang <cong.wang@bytedance.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Link: https://lore.kernel.org/bpf/20211115044006.26068-1-xiyou.wangcong@gmail.com
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/udp.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 319dd7bbfe33..8bcecdd6aeda 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1807,6 +1807,17 @@ int udp_read_sock(struct sock *sk, read_descriptor_t *desc, skb = skb_recv_udp(sk, 0, 1, &err); if (!skb) return err; + + if (udp_lib_checksum_complete(skb)) { + __UDP_INC_STATS(sock_net(sk), UDP_MIB_CSUMERRORS, + IS_UDPLITE(sk)); + __UDP_INC_STATS(sock_net(sk), UDP_MIB_INERRORS, + IS_UDPLITE(sk)); + atomic_inc(&sk->sk_drops); + kfree_skb(skb); + continue; + } + used = recv_actor(desc, skb, 0, skb->len); if (used <= 0) { if (!copied) |