From mboxrd@z Thu Jan 1 00:00:00 1970 From: Liu Yu Subject: [PATCH] tcp_cubic: fix divide error when SYN flood Date: Tue, 22 Apr 2014 10:40:15 +0800 Message-ID: <5355D68F.2060107@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=GB2312 Content-Transfer-Encoding: 7bit Cc: netdev@vger.kernel.org To: "David S. Miller" , Alexey Kuznetsov , Stephen Hemminger Return-path: Received: from mail-pb0-f46.google.com ([209.85.160.46]:41743 "EHLO mail-pb0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751276AbaDVCin (ORCPT ); Mon, 21 Apr 2014 22:38:43 -0400 Received: by mail-pb0-f46.google.com with SMTP id rq2so4407641pbb.33 for ; Mon, 21 Apr 2014 19:38:43 -0700 (PDT) Sender: netdev-owner@vger.kernel.org List-ID: From: Liu Yu 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 Signed-off-by: Liu Yu --- 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