commit:     b8d213a1983935e8741527f7a87ff63f1a44e648
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Fri Apr 14 19:17:28 2017 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Fri Apr 14 19:17:28 2017 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=b8d213a1

Fix for CVE-2016-10229. Unsafe second checksum calculation in udp.c. See bug 
#615480.

 0000_README                                        |  4 +
 ...udp-prop-suprt-MSG-PEEK-wth-trunc-buffers.patch | 94 ++++++++++++++++++++++
 2 files changed, 98 insertions(+)

diff --git a/0000_README b/0000_README
index 80a401b..c91ff69 100644
--- a/0000_README
+++ b/0000_README
@@ -211,6 +211,10 @@ Patch:  1520_CVE-2017-6074-dccp-skb-freeing-fix.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=610600
 Desc:   dccp: fix freeing skb too early for IPV6_RECVPKTINFO. CVE-2017-6074
 
+Patch:  1530_udp-prop-suprt-MSG-PEEK-wth-trunc-buffers.patch
+From:   https://bugs.gentoo.org/show_bug.cgi?id=615480
+Desc:   Fixes CVE-2016-10229. Unsafe second checksum calculation in udp.c
+
 Patch:  1800_fix-lru-cache-add-oom-regression.patch
 From:   http://thread.gmane.org/gmane.linux.kernel.stable/184384
 Desc:   Revert commit 8f182270dfec mm/swap.c: flush lru pvecs on compound page 
arrival to fix OOM error.

diff --git a/1530_udp-prop-suprt-MSG-PEEK-wth-trunc-buffers.patch 
b/1530_udp-prop-suprt-MSG-PEEK-wth-trunc-buffers.patch
new file mode 100644
index 0000000..1d12eaa
--- /dev/null
+++ b/1530_udp-prop-suprt-MSG-PEEK-wth-trunc-buffers.patch
@@ -0,0 +1,94 @@
+From 197c949e7798fbf28cfadc69d9ca0c2abbf93191 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <eduma...@google.com>
+Date: Wed, 30 Dec 2015 08:51:12 -0500
+Subject: udp: properly support MSG_PEEK with truncated buffers
+
+Backport of this upstream commit into stable kernels :
+89c22d8c3b27 ("net: Fix skb csum races when peeking")
+exposed a bug in udp stack vs MSG_PEEK support, when user provides
+a buffer smaller than skb payload.
+
+In this case,
+skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr),
+                                 msg->msg_iov);
+returns -EFAULT.
+
+This bug does not happen in upstream kernels since Al Viro did a great
+job to replace this into :
+skb_copy_and_csum_datagram_msg(skb, sizeof(struct udphdr), msg);
+This variant is safe vs short buffers.
+
+For the time being, instead reverting Herbert Xu patch and add back
+skb->ip_summed invalid changes, simply store the result of
+udp_lib_checksum_complete() so that we avoid computing the checksum a
+second time, and avoid the problematic
+skb_copy_and_csum_datagram_iovec() call.
+
+This patch can be applied on recent kernels as it avoids a double
+checksumming, then backported to stable kernels as a bug fix.
+
+Signed-off-by: Eric Dumazet <eduma...@google.com>
+Acked-by: Herbert Xu <herb...@gondor.apana.org.au>
+Signed-off-by: David S. Miller <da...@davemloft.net>
+---
+ net/ipv4/udp.c | 6 ++++--
+ net/ipv6/udp.c | 6 ++++--
+ 2 files changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index 8841e98..ac14ae4 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -1271,6 +1271,7 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, 
size_t len, int noblock,
+       int peeked, off = 0;
+       int err;
+       int is_udplite = IS_UDPLITE(sk);
++      bool checksum_valid = false;
+       bool slow;
+ 
+       if (flags & MSG_ERRQUEUE)
+@@ -1296,11 +1297,12 @@ try_again:
+        */
+ 
+       if (copied < ulen || UDP_SKB_CB(skb)->partial_cov) {
+-              if (udp_lib_checksum_complete(skb))
++              checksum_valid = !udp_lib_checksum_complete(skb);
++              if (!checksum_valid)
+                       goto csum_copy_err;
+       }
+ 
+-      if (skb_csum_unnecessary(skb))
++      if (checksum_valid || skb_csum_unnecessary(skb))
+               err = skb_copy_datagram_msg(skb, sizeof(struct udphdr),
+                                           msg, copied);
+       else {
+diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
+index 9da3287..00775ee 100644
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -402,6 +402,7 @@ int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, 
size_t len,
+       int peeked, off = 0;
+       int err;
+       int is_udplite = IS_UDPLITE(sk);
++      bool checksum_valid = false;
+       int is_udp4;
+       bool slow;
+ 
+@@ -433,11 +434,12 @@ try_again:
+        */
+ 
+       if (copied < ulen || UDP_SKB_CB(skb)->partial_cov) {
+-              if (udp_lib_checksum_complete(skb))
++              checksum_valid = !udp_lib_checksum_complete(skb);
++              if (!checksum_valid)
+                       goto csum_copy_err;
+       }
+ 
+-      if (skb_csum_unnecessary(skb))
++      if (checksum_valid || skb_csum_unnecessary(skb))
+               err = skb_copy_datagram_msg(skb, sizeof(struct udphdr),
+                                           msg, copied);
+       else {
+-- 
+cgit v1.1
+

Reply via email to