Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 3139

kernel-2.6.18-238.el5.src.rpm

From: Neil Horman <nhorman@redhat.com>
Date: Thu, 12 Aug 2010 18:05:30 -0400
Subject: [net] tcp: fix div by zero in congestion control protos
Message-id: <20100812180530.GB7251@shamino.rdu.redhat.com>
Patchwork-id: 27526
O-Subject: [RHEL 5.6 PATCH] tcp: fix div by zero oops in vegas and veno
	congestion control (608641)
Bugzilla: 608641
RH-Acked-by: David S. Miller <davem@redhat.com>
RH-Acked-by: Jiri Olsa <jolsa@redhat.com>
RH-Acked-by: Ivan Vecera <ivecera@redhat.com>

Hey all-
	We had several crashes reported in bug  608641, which were caused by
division by zero in the tcp vegas congestion controll algorithm.  Upstream
seemed to solve this problem (perhaps inadvertently) with commit
30cfd0baf0a0c4329fff1ef4b622919297969ec8, which did a sign check on the rtt
value.  Since getting that commit back to RHEL5 is pretty impossible as the
supporting patches would be abi breakers, this is an approximation of that fix.
Confirmed to fix bz 608641

Signed-off-by: Jarod Wilson <jarod@redhat.com>

diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index e9aa763..44c7718 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2249,7 +2249,7 @@ static int tcp_tso_acked(struct sock *sk, struct sk_buff *skb,
 	return acked;
 }
 
-static u32 tcp_usrtt(struct timeval *tv)
+static s32 tcp_usrtt(struct timeval *tv)
 {
 	struct timeval now;
 
diff --git a/net/ipv4/tcp_vegas.c b/net/ipv4/tcp_vegas.c
index 8a57a56..5635671 100644
--- a/net/ipv4/tcp_vegas.c
+++ b/net/ipv4/tcp_vegas.c
@@ -116,10 +116,13 @@ static void tcp_vegas_init(struct sock *sk)
  *   o min-filter RTT samples from a much longer window (forever for now)
  *     to find the propagation delay (baseRTT)
  */
-static void tcp_vegas_rtt_calc(struct sock *sk, u32 usrtt)
+static void tcp_vegas_rtt_calc(struct sock *sk, s32 usrtt)
 {
 	struct vegas *vegas = inet_csk_ca(sk);
-	u32 vrtt = usrtt + 1; /* Never allow zero rtt or baseRTT */
+	s32 vrtt = usrtt + 1; /* Never allow zero rtt or baseRTT */
+
+	if (vrtt <= 0)
+		return;
 
 	/* Filter to find propagation delay: */
 	if (vrtt < vegas->baseRTT)
diff --git a/net/ipv4/tcp_veno.c b/net/ipv4/tcp_veno.c
index 35baea6..d34d0c4 100644
--- a/net/ipv4/tcp_veno.c
+++ b/net/ipv4/tcp_veno.c
@@ -69,10 +69,13 @@ static void tcp_veno_init(struct sock *sk)
 }
 
 /* Do rtt sampling needed for Veno. */
-static void tcp_veno_rtt_calc(struct sock *sk, u32 usrtt)
+static void tcp_veno_rtt_calc(struct sock *sk, s32 usrtt)
 {
 	struct veno *veno = inet_csk_ca(sk);
-	u32 vrtt = usrtt + 1;	/* Never allow zero rtt or basertt */
+	s32 vrtt = usrtt + 1;	/* Never allow zero rtt or basertt */
+
+	if (vrtt <= 0)
+		return;
 
 	/* Filter to find propagation delay: */
 	if (vrtt < veno->basertt)