summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCong Wang <cong.wang@bytedance.com>2021-11-14 20:40:06 -0800
committerDaniel Borkmann <daniel@iogearbox.net>2021-11-16 13:18:23 +0100
commit099f896f498a2b26d84f4ddae039b2c542c18b48 (patch)
tree0b9515284b4d457b6d265a367752a7f1ab309ce2
parent353050be4c19e102178ccc05988101887c25ae53 (diff)
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
-rw-r--r--net/ipv4/udp.c11
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)