From c78cb49a3b432cabe54804b462a6a83e6dda1cfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= Date: Tue, 7 Nov 2023 18:27:50 +0100 Subject: [PATCH] BUG/MEDIUM: quic: Avoid trying to send ACK frames from an empty ack ranges tree This may happen upon ack ranges allocation failures (from quic_update_ack_ranges_list(). This can lead to empty trees of ack ranges to be used to build ACK frames which is not good at all. Furthermore this is detected by a BUG_ON() (in qc_do_build_pkt()). To avoid this, simply update the acknowledgemen state of the connection only if quic_update_ack_ranges_list() succeeds, as it fails only in case of memory allocation failures. Must be backported as far as 2.6. --- src/quic_rx.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/quic_rx.c b/src/quic_rx.c index e2f3f8956..37ab52176 100644 --- a/src/quic_rx.c +++ b/src/quic_rx.c @@ -1381,23 +1381,27 @@ int qc_treat_rx_pkts(struct quic_conn *qc) else { struct quic_arng ar = { .first = pkt->pn, .last = pkt->pn }; - if (pkt->flags & QUIC_FL_RX_PACKET_ACK_ELICITING) { - int arm_ack_timer = - qc->state >= QUIC_HS_ST_COMPLETE && - qel->pktns == qc->apktns; - - qel->pktns->flags |= QUIC_FL_PKTNS_ACK_REQUIRED; - qel->pktns->rx.nb_aepkts_since_last_ack++; - qc_idle_timer_rearm(qc, 1, arm_ack_timer); - } - if (pkt->pn > largest_pn) { - largest_pn = pkt->pn; - largest_pn_time_received = pkt->time_received; - } /* Update the list of ranges to acknowledge. */ - if (!quic_update_ack_ranges_list(qc, &qel->pktns->rx.arngs, &ar)) + if (quic_update_ack_ranges_list(qc, &qel->pktns->rx.arngs, &ar)) { + if (pkt->flags & QUIC_FL_RX_PACKET_ACK_ELICITING) { + int arm_ack_timer = + qc->state >= QUIC_HS_ST_COMPLETE && + qel->pktns == qc->apktns; + + qel->pktns->flags |= QUIC_FL_PKTNS_ACK_REQUIRED; + qel->pktns->rx.nb_aepkts_since_last_ack++; + qc_idle_timer_rearm(qc, 1, arm_ack_timer); + } + + if (pkt->pn > largest_pn) { + largest_pn = pkt->pn; + largest_pn_time_received = pkt->time_received; + } + } + else { TRACE_ERROR("Could not update ack range list", QUIC_EV_CONN_RXPKT, qc); + } } } node = eb64_next(node);