| From foo@baz Sat Jun 13 09:48:35 PDT 2015 |
| From: Eric Dumazet <edumazet@google.com> |
| Date: Sat, 30 May 2015 09:16:53 -0700 |
| Subject: udp: fix behavior of wrong checksums |
| |
| From: Eric Dumazet <edumazet@google.com> |
| |
| [ Upstream commit beb39db59d14990e401e235faf66a6b9b31240b0 ] |
| |
| 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. |
| |
| Signed-off-by: Eric Dumazet <edumazet@google.com> |
| Cc: Willem de Bruijn <willemb@google.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| net/ipv4/udp.c | 6 ++---- |
| net/ipv6/udp.c | 6 ++---- |
| 2 files changed, 4 insertions(+), 8 deletions(-) |
| |
| --- a/net/ipv4/udp.c |
| +++ b/net/ipv4/udp.c |
| @@ -1348,10 +1348,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; |
| } |
| --- a/net/ipv6/udp.c |
| +++ b/net/ipv6/udp.c |
| @@ -528,10 +528,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; |
| } |