From fae92068989f23802daf3ee05edd672d962ab9ee Mon Sep 17 00:00:00 2001 From: Eric Dumazet <edumazet@google.com> Date: Sat, 30 May 2015 09:16:53 -0700 Subject: [PATCH] UPSTREAM: udp: fix behavior of wrong checksums We have two problems in UDP stack related to bogus checksums : 1) We return -EAGAIN to application even if receive queue is not empty. This breaks applications using edge trigger epoll() 2) Under UDP flood, we can loop forever without yielding to other processes, potentially hanging the host, especially on non SMP. This patch is an attempt to make things better. We might in the future add extra support for rt applications wanting to better control time spent doing a recv() in a hostile environment. For example we could validate checksums before queuing packets in socket receive queue. Bug:29507402 Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Willem de Bruijn <willemb@google.com> Signed-off-by: David S. Miller <davem@davemloft.net> (cherry picked from commit beb39db59d14990e401e235faf66a6b9b31240b0) Change-Id: I0096f0660d8951184f3a3b49a78702924f766cea --- net/ipv4/udp.c | 6 ++---- net/ipv6/udp.c | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 1c9d2685de3f..b3ab3279568e 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1294,10 +1294,8 @@ csum_copy_err: } unlock_sock_fast(sk, slow); - if (noblock) - return -EAGAIN; - - /* starting over for a new packet */ + /* starting over for a new packet, but check if we need to yield */ + cond_resched(); msg->msg_flags &= ~MSG_TRUNC; goto try_again; } diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index b01d23d2ec8a..25f3babd59d4 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -494,10 +494,8 @@ csum_copy_err: } unlock_sock_fast(sk, slow); - if (noblock) - return -EAGAIN; - - /* starting over for a new packet */ + /* starting over for a new packet, but check if we need to yield */ + cond_resched(); msg->msg_flags &= ~MSG_TRUNC; goto try_again; } -- GitLab