Subject: [PATCH] tcp_cubic: fix divide error when SYN flood

From: Liu Yu <[email-masked]>
Date: Tue, 22 Apr 2014 10:40:15 +0800

From: Liu Yu <[email-masked]>

commit b9f47a3aaeab (tcp_cubic: limit delayed_ack ratio to prevent
divide error) try to prevent divide error, but it still has a little
chance that delayed_ack can reach zero. In case machine sufferring
continuous SYN flood, the argument cnt could be big, and so that
ratio+cnt could get overflow and may happen to be zero. If so,
min(ratio, ACK_RATIO_LIMIT) will calculate to be zero.

The crash log may like this:
..
 <6>[27536.083145] possible SYN flooding on port 8080. Sending cookies.
 <6>[27596.092124] possible SYN flooding on port 8080. Sending cookies.
 <6>[27656.109832] possible SYN flooding on port 8080. Sending cookies.
 <0>[27676.940730] divide error: 0000 [#1] SMP
 <0>[27676.987890] last sysfs file: /sys/class/scsi_host/host0/proc_name
..

CC: Stephen Hemminger <[email-masked]>
Signed-off-by: Liu Yu <[email-masked]>
---
 net/ipv4/tcp_cubic.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c
index 8bf2245..9d332b9 100644
--- a/net/ipv4/tcp_cubic.c
+++ b/net/ipv4/tcp_cubic.c
@@ -404,12 +404,12 @@ static void bictcp_acked(struct sock *sk, u32 cnt, s32 rtt_us)
 	u32 delay;
 
 	if (icsk->icsk_ca_state == TCP_CA_Open) {
-		u32 ratio = ca->delayed_ack;
+		u64 ratio = ca->delayed_ack;
 
 		ratio -= ca->delayed_ack >> ACK_RATIO_SHIFT;
 		ratio += cnt;
 
-		ca->delayed_ack = min(ratio, ACK_RATIO_LIMIT);
+		ca->delayed_ack = min_t(u64, ratio, ACK_RATIO_LIMIT);
 	}
 
 	/* Some calls are for duplicates without timetamps */
-- 
1.7.1