[linux] 01/01: udp: properly support MSG_PEEK with truncated buffers (Closes: #808293, regression in 3.16.7-ckt17)

debian-kernel at lists.debian.org debian-kernel at lists.debian.org
Sat Jan 2 02:06:20 UTC 2016


This is an automated email from the git hooks/post-receive script.

benh pushed a commit to branch jessie-security
in repository linux.

commit 3d5f32a7504cec63bc543765ea960b665dbd089e
Author: Ben Hutchings <ben at decadent.org.uk>
Date:   Sat Jan 2 02:02:23 2016 +0000

    udp: properly support MSG_PEEK with truncated buffers (Closes: #808293, regression in 3.16.7-ckt17)
---
 debian/changelog                                   |  2 +
 ...ument-to-skb_copy_and_csum_datagram_iovec.patch | 95 ++++++++++++++++++++++
 ...y-support-msg_peek-with-truncated-buffers.patch | 88 ++++++++++++++++++++
 debian/patches/series                              |  2 +
 4 files changed, 187 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index a1150d3..52dea2e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -10,6 +10,8 @@ linux (3.16.7-ckt20-1+deb8u2) UNRELEASED; urgency=medium
   * KEYS: Fix race between read and revoke (CVE-2015-7550)
   * [x86] KVM: Reload pit counters for all channels when restoring state
     (CVE-2015-7513)
+  * udp: properly support MSG_PEEK with truncated buffers
+    (Closes: #808293, regression in 3.16.7-ckt17)
 
  -- Ben Hutchings <ben at decadent.org.uk>  Sun, 27 Dec 2015 14:20:54 +0000
 
diff --git a/debian/patches/bugfix/all/revert-net-add-length-argument-to-skb_copy_and_csum_datagram_iovec.patch b/debian/patches/bugfix/all/revert-net-add-length-argument-to-skb_copy_and_csum_datagram_iovec.patch
new file mode 100644
index 0000000..25d1a64
--- /dev/null
+++ b/debian/patches/bugfix/all/revert-net-add-length-argument-to-skb_copy_and_csum_datagram_iovec.patch
@@ -0,0 +1,95 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Date: Sat, 02 Jan 2016 01:11:55 +0000
+Subject: Revert "net: add length argument to skb_copy_and_csum_datagram_iovec"
+Bug-Debian: https://bugs.debian.org/808293
+
+This reverts commit fa89ae5548ed282f0ceb4660b3b93e4e2ee875f3.  That fixed
+the problem of buffer over-reads introduced by backporting commit
+89c22d8c3b27 ("net: Fix skb csum races when peeking"), but resulted in
+incorrect checksumming for short reads.  It will be replaced with a
+complete fix.
+
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+---
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -2525,7 +2525,7 @@
+ int skb_copy_datagram_iovec(const struct sk_buff *from, int offset,
+ 			    struct iovec *to, int size);
+ int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb, int hlen,
+-				     struct iovec *iov, int len);
++				     struct iovec *iov);
+ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
+ 				 const struct iovec *from, int from_offset,
+ 				 int len);
+--- a/net/core/datagram.c
++++ b/net/core/datagram.c
+@@ -818,7 +818,6 @@
+  *	@skb: skbuff
+  *	@hlen: hardware length
+  *	@iov: io vector
+- *	@len: amount of data to copy from skb to iov
+  *
+  *	Caller _must_ check that skb will fit to this iovec.
+  *
+@@ -828,14 +827,11 @@
+  *			   can be modified!
+  */
+ int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb,
+-				     int hlen, struct iovec *iov, int len)
++				     int hlen, struct iovec *iov)
+ {
+ 	__wsum csum;
+ 	int chunk = skb->len - hlen;
+ 
+-	if (chunk > len)
+-		chunk = len;
+-
+ 	if (!chunk)
+ 		return 0;
+ 
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -4906,7 +4906,7 @@
+ 		err = skb_copy_datagram_iovec(skb, hlen, tp->ucopy.iov, chunk);
+ 	else
+ 		err = skb_copy_and_csum_datagram_iovec(skb, hlen,
+-						       tp->ucopy.iov, chunk);
++						       tp->ucopy.iov);
+ 
+ 	if (!err) {
+ 		tp->ucopy.len -= chunk;
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -1307,7 +1307,7 @@
+ 	else {
+ 		err = skb_copy_and_csum_datagram_iovec(skb,
+ 						       sizeof(struct udphdr),
+-						       msg->msg_iov, copied);
++						       msg->msg_iov);
+ 
+ 		if (err == -EINVAL)
+ 			goto csum_copy_err;
+--- a/net/ipv6/raw.c
++++ b/net/ipv6/raw.c
+@@ -492,7 +492,7 @@
+ 			goto csum_copy_err;
+ 		err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+ 	} else {
+-		err = skb_copy_and_csum_datagram_iovec(skb, 0, msg->msg_iov, copied);
++		err = skb_copy_and_csum_datagram_iovec(skb, 0, msg->msg_iov);
+ 		if (err == -EINVAL)
+ 			goto csum_copy_err;
+ 	}
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -428,8 +428,7 @@
+ 		err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
+ 					      msg->msg_iov, copied);
+ 	else {
+-		err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr),
+-						       msg->msg_iov, copied);
++		err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov);
+ 		if (err == -EINVAL)
+ 			goto csum_copy_err;
+ 	}
diff --git a/debian/patches/bugfix/all/udp-properly-support-msg_peek-with-truncated-buffers.patch b/debian/patches/bugfix/all/udp-properly-support-msg_peek-with-truncated-buffers.patch
new file mode 100644
index 0000000..f74d86f
--- /dev/null
+++ b/debian/patches/bugfix/all/udp-properly-support-msg_peek-with-truncated-buffers.patch
@@ -0,0 +1,88 @@
+From: Eric Dumazet <edumazet at google.com>
+Date: Wed, 30 Dec 2015 08:51:12 -0500
+Subject: udp: properly support MSG_PEEK with truncated  buffers
+Bug-Debian: https://bugs.debian.org/808293
+Origin: http://article.gmane.org/gmane.linux.kernel.stable/159132
+
+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 <edumazet at google.com>
+[bwh: Backported to 3.16: adjust context]
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+---
+ net/ipv4/udp.c |    6 ++++--
+ net/ipv6/udp.c |    6 ++++--
+ 2 files changed, 8 insertions(+), 4 deletions(-)
+
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -1274,6 +1274,7 @@ int udp_recvmsg(struct kiocb *iocb, stru
+ 	int peeked, off = 0;
+ 	int err;
+ 	int is_udplite = IS_UDPLITE(sk);
++	bool checksum_valid = false;
+ 	bool slow;
+ 
+ 	if (flags & MSG_ERRQUEUE)
+@@ -1299,11 +1300,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_iovec(skb, sizeof(struct udphdr),
+ 					      msg->msg_iov, copied);
+ 	else {
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -389,6 +389,7 @@ int udpv6_recvmsg(struct kiocb *iocb, st
+ 	int peeked, off = 0;
+ 	int err;
+ 	int is_udplite = IS_UDPLITE(sk);
++	bool checksum_valid = false;
+ 	int is_udp4;
+ 	bool slow;
+ 
+@@ -420,11 +421,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_iovec(skb, sizeof(struct udphdr),
+ 					      msg->msg_iov, copied);
+ 	else {
diff --git a/debian/patches/series b/debian/patches/series
index 7aae595..bd98bbd 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -667,3 +667,5 @@ bugfix/all/ptrace-being-capable-wrt-a-process-requires-mapped-uids-gids.patch
 debian/ptrace-fix-abi-change-for-priv-esc-fix.patch
 bugfix/all/keys-fix-race-between-read-and-revoke.patch
 bugfix/x86/KVM-x86-Reload-pit-counters-for-all-channels-when-re.patch
+bugfix/all/revert-net-add-length-argument-to-skb_copy_and_csum_datagram_iovec.patch
+bugfix/all/udp-properly-support-msg_peek-with-truncated-buffers.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/kernel/linux.git



More information about the Kernel-svn-changes mailing list