From 595251f22eb7b6bfa8b797e32c3326f5ad9ef07a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= Date: Thu, 13 Apr 2023 10:46:42 +0200 Subject: [PATCH] BUG/MINOR: quic: SIGFPE in quic_cubic_update() As reported by @Tristan971 in GH #2116, the congestion control window could be zero due to an inversion in the code about the reduction factor to be applied. On a new loss event, it must be applied to the slow start threshold and the window should never be below ->min_cwnd (2*max_udp_payload_sz). Same issue in both newReno and cubic algorithm. Furthermore in newReno, only the threshold was decremented. Must be backported to 2.6 and 2.7. --- src/quic_cc_cubic.c | 4 ++-- src/quic_cc_newreno.c | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/quic_cc_cubic.c b/src/quic_cc_cubic.c index d22897b..fd7fef5 100644 --- a/src/quic_cc_cubic.c +++ b/src/quic_cc_cubic.c @@ -197,8 +197,8 @@ static void quic_enter_recovery(struct quic_cc *cc) else { c->last_w_max = path->cwnd; } - path->cwnd = (CUBIC_BETA * path->cwnd) >> CUBIC_BETA_SCALE_SHIFT; - c->ssthresh = QUIC_MAX(path->cwnd, path->min_cwnd); + c->ssthresh = (CUBIC_BETA * path->cwnd) >> CUBIC_BETA_SCALE_SHIFT; + path->cwnd = QUIC_MAX(c->ssthresh, (uint32_t)path->min_cwnd); c->state = QUIC_CC_ST_RP; TRACE_LEAVE(QUIC_EV_CONN_CC, cc->qc, NULL, cc); } diff --git a/src/quic_cc_newreno.c b/src/quic_cc_newreno.c index 65763d7..9b13248 100644 --- a/src/quic_cc_newreno.c +++ b/src/quic_cc_newreno.c @@ -71,7 +71,8 @@ static void quic_cc_nr_enter_recovery(struct quic_cc *cc) path = container_of(cc, struct quic_path, cc); nr->recovery_start_time = now_ms; - nr->ssthresh = QUIC_MAX(path->cwnd >> 1, path->min_cwnd); + nr->ssthresh = path->cwnd >> 1; + path->cwnd = QUIC_MAX(nr->ssthresh, (uint32_t)path->min_cwnd); nr->state = QUIC_CC_ST_RP; } -- 1.7.10.4