[linux] 01/01: udp: properly support MSG_PEEK with truncated buffers (Closes: #808293, regression in 2.6.32.69)
debian-kernel at lists.debian.org
debian-kernel at lists.debian.org
Sat Jan 2 02:06:50 UTC 2016
This is an automated email from the git hooks/post-receive script.
benh pushed a commit to branch squeeze-security
in repository linux.
commit 849f7353f683b2a63804da8476feaa2256b6cee9
Author: Ben Hutchings <ben at decadent.org.uk>
Date: Sat Jan 2 01:53:16 2016 +0000
udp: properly support MSG_PEEK with truncated buffers (Closes: #808293, regression in 2.6.32.69)
---
debian/changelog | 2 +
...ument-to-skb_copy_and_csum_datagram_iovec.patch | 108 +++++++++++++++++++++
...y-support-msg_peek-with-truncated-buffers.patch | 88 +++++++++++++++++
debian/patches/series/48squeeze18 | 2 +
4 files changed, 200 insertions(+)
diff --git a/debian/changelog b/debian/changelog
index e9f89d5..3b71262 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -3,6 +3,8 @@ linux-2.6 (2.6.32-48squeeze18) UNRELEASED; urgency=medium
* net: add validation for the socket syscall protocol argument (CVE-2015-8543)
* bluetooth: Validate socket address length in sco_sock_bind() (CVE-2015-8575)
* KEYS: Fix race between read and revoke (CVE-2015-7550)
+ * udp: properly support MSG_PEEK with truncated buffers
+ (Closes: #808293, regression in 2.6.32.69)
-- Ben Hutchings <ben at decadent.org.uk> Sun, 27 Dec 2015 20:06:05 +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..c47ee65
--- /dev/null
+++ b/debian/patches/bugfix/all/revert-net-add-length-argument-to-skb_copy_and_csum_datagram_iovec.patch
@@ -0,0 +1,108 @@
+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 c507639ba963bb47e3f515670a7cace76af76ab6. 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
+@@ -1775,8 +1775,7 @@ extern int skb_copy_datagram_iove
+ int size);
+ extern int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb,
+ int hlen,
+- struct iovec *iov,
+- int len);
++ struct iovec *iov);
+ extern int skb_copy_datagram_from_iovec(struct sk_buff *skb,
+ int offset,
+ const struct iovec *from,
+--- a/net/core/datagram.c
++++ b/net/core/datagram.c
+@@ -693,7 +693,6 @@ EXPORT_SYMBOL(__skb_checksum_complete);
+ * @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.
+ *
+@@ -703,14 +702,11 @@ EXPORT_SYMBOL(__skb_checksum_complete);
+ * 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
+@@ -4985,7 +4985,7 @@ static int tcp_copy_to_iovec(struct sock
+ 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
+@@ -975,7 +975,7 @@ try_again:
+ 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
+@@ -476,7 +476,7 @@ static int rawv6_recvmsg(struct kiocb *i
+ 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
+@@ -233,8 +233,7 @@ try_again:
+ 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;
+ }
+--- a/net/rxrpc/ar-recvmsg.c
++++ b/net/rxrpc/ar-recvmsg.c
+@@ -184,8 +184,7 @@ int rxrpc_recvmsg(struct kiocb *iocb, st
+ msg->msg_iov, copy);
+ } else {
+ ret = skb_copy_and_csum_datagram_iovec(skb, offset,
+- msg->msg_iov,
+- copy);
++ msg->msg_iov);
+ if (ret == -EINVAL)
+ goto csum_copy_error;
+ }
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..1594cd3
--- /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 2.6.32: 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
+@@ -941,6 +941,7 @@ int udp_recvmsg(struct kiocb *iocb, stru
+ int peeked;
+ int err;
+ int is_udplite = IS_UDPLITE(sk);
++ bool checksum_valid = false;
+
+ if (flags & MSG_ERRQUEUE)
+ return ip_recv_error(sk, msg, len, addr_len);
+@@ -965,11 +966,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
+@@ -198,6 +198,7 @@ int udpv6_recvmsg(struct kiocb *iocb, st
+ int peeked;
+ int err;
+ int is_udplite = IS_UDPLITE(sk);
++ bool checksum_valid = false;
+ int is_udp4;
+
+ if (flags & MSG_ERRQUEUE)
+@@ -225,11 +226,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/48squeeze18 b/debian/patches/series/48squeeze18
index 23b0906..96b328d 100644
--- a/debian/patches/series/48squeeze18
+++ b/debian/patches/series/48squeeze18
@@ -1,3 +1,5 @@
+ bugfix/all/net-add-validation-for-the-socket-syscall-protocol-a.patch
+ bugfix/all/bluetooth-validate-socket-address-length-in-sco_sock.patch
+ bugfix/all/keys-fix-race-between-read-and-revoke.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