[linux] 01/01: tcp: fix zero cwnd in tcp_cwnd_reduction (CVE-2016-2070)

debian-kernel at lists.debian.org debian-kernel at lists.debian.org
Tue Jan 26 08:00:47 UTC 2016


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

carnil pushed a commit to branch sid
in repository linux.

commit cdfc3b2f3067d742a3cdc0e18498c2fb20bcb19f
Author: Salvatore Bonaccorso <carnil at debian.org>
Date:   Tue Jan 26 08:58:09 2016 +0100

    tcp: fix zero cwnd in tcp_cwnd_reduction (CVE-2016-2070)
---
 debian/changelog                                   |  3 ++
 .../tcp-fix-zero-cwnd-in-tcp_cwnd_reduction.patch  | 63 ++++++++++++++++++++++
 debian/patches/series                              |  1 +
 3 files changed, 67 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index c7bce85..0fa86ab 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -54,6 +54,9 @@ linux (4.3.4-1) UNRELEASED; urgency=medium
   [ Ben Hutchings ]
   * fuse: break infinite loop in fuse_fill_write_pages() (CVE-2015-8785)
 
+  [ Salvatore Bonaccorso ]
+  tcp: fix zero cwnd in tcp_cwnd_reduction (CVE-2016-2070)
+
  -- Ben Hutchings <ben at decadent.org.uk>  Sat, 23 Jan 2016 11:51:46 +0000
 
 linux (4.3.3-7) unstable; urgency=medium
diff --git a/debian/patches/bugfix/all/tcp-fix-zero-cwnd-in-tcp_cwnd_reduction.patch b/debian/patches/bugfix/all/tcp-fix-zero-cwnd-in-tcp_cwnd_reduction.patch
new file mode 100644
index 0000000..bd192a1
--- /dev/null
+++ b/debian/patches/bugfix/all/tcp-fix-zero-cwnd-in-tcp_cwnd_reduction.patch
@@ -0,0 +1,63 @@
+From: Yuchung Cheng <ycheng at google.com>
+Date: Wed, 6 Jan 2016 12:42:38 -0800
+Subject: tcp: fix zero cwnd in tcp_cwnd_reduction
+Origin: https://git.kernel.org/linus/8b8a321ff72c785ed5e8b4cf6eda20b35d427390
+
+Patch 3759824da87b ("tcp: PRR uses CRB mode by default and SS mode
+conditionally") introduced a bug that cwnd may become 0 when both
+inflight and sndcnt are 0 (cwnd = inflight + sndcnt). This may lead
+to a div-by-zero if the connection starts another cwnd reduction
+phase by setting tp->prior_cwnd to the current cwnd (0) in
+tcp_init_cwnd_reduction().
+
+To prevent this we skip PRR operation when nothing is acked or
+sacked. Then cwnd must be positive in all cases as long as ssthresh
+is positive:
+
+1) The proportional reduction mode
+   inflight > ssthresh > 0
+
+2) The reduction bound mode
+  a) inflight == ssthresh > 0
+
+  b) inflight < ssthresh
+     sndcnt > 0 since newly_acked_sacked > 0 and inflight < ssthresh
+
+Therefore in all cases inflight and sndcnt can not both be 0.
+We check invalid tp->prior_cwnd to avoid potential div0 bugs.
+
+In reality this bug is triggered only with a sequence of less common
+events.  For example, the connection is terminating an ECN-triggered
+cwnd reduction with an inflight 0, then it receives reordered/old
+ACKs or DSACKs from prior transmission (which acks nothing). Or the
+connection is in fast recovery stage that marks everything lost,
+but fails to retransmit due to local issues, then receives data
+packets from other end which acks nothing.
+
+Fixes: 3759824da87b ("tcp: PRR uses CRB mode by default and SS mode conditionally")
+Reported-by: Oleksandr Natalenko <oleksandr at natalenko.name>
+Signed-off-by: Yuchung Cheng <ycheng at google.com>
+Signed-off-by: Neal Cardwell <ncardwell at google.com>
+Signed-off-by: Eric Dumazet <edumazet at google.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ net/ipv4/tcp_input.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index 2d656ee..d4c5115 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -2478,6 +2478,9 @@ static void tcp_cwnd_reduction(struct sock *sk, const int prior_unsacked,
+ 	int newly_acked_sacked = prior_unsacked -
+ 				 (tp->packets_out - tp->sacked_out);
+ 
++	if (newly_acked_sacked <= 0 || WARN_ON_ONCE(!tp->prior_cwnd))
++		return;
++
+ 	tp->prr_delivered += newly_acked_sacked;
+ 	if (delta < 0) {
+ 		u64 dividend = (u64)tp->snd_ssthresh * tp->prr_delivered +
+-- 
+2.1.4
+
diff --git a/debian/patches/series b/debian/patches/series
index 94af25d..ff4957e 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -141,3 +141,4 @@ bugfix/all/bcache-allows-use-of-register-in-udev-to-avoid-devic.patch
 bugfix/all/bcache-prevent-crash-on-changing-writeback_running.patch
 bugfix/all/bcache-change-refill_dirty-to-always-scan-entire-dis.patch
 bugfix/all/fuse-break-infinite-loop-in-fuse_fill_write_pages.patch
+bugfix/all/tcp-fix-zero-cwnd-in-tcp_cwnd_reduction.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