From: Frédéric Lécaille Date: Wed, 13 Dec 2023 10:45:43 +0000 (+0100) Subject: BUG/MEDIUM: quic: QUIC CID removed from tree without locking X-Git-Tag: v3.0-dev1~100 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dd58dff1e6;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: quic: QUIC CID removed from tree without locking This bug arrived with this commit: BUG/MINOR: quic: Wrong RETIRE_CONNECTION_ID sequence number chec Every connection ID manipulations against the by thread trees used to store the connection IDs must be done under the trees locks. These trees are accessed by the low level connection identification code. When receiving a RETIRE_CONNECTION_ID frame, the concerned connection ID must be deleted from the its underlying by thread tree but not without locking! Add a WR lock around ebmb_delete() call to do so. Must be backported as far as 2.7. --- diff --git a/src/quic_rx.c b/src/quic_rx.c index d136efdf89..9e55aa34ed 100644 --- a/src/quic_rx.c +++ b/src/quic_rx.c @@ -996,6 +996,7 @@ static int qc_parse_pkt_frms(struct quic_conn *qc, struct quic_rx_packet *pkt, break; case QUIC_FT_RETIRE_CONNECTION_ID: { + struct quic_cid_tree *tree; struct quic_connection_id *conn_id = NULL; if (!qc_handle_retire_connection_id_frm(qc, &frm, &pkt->dcid, &conn_id)) @@ -1004,7 +1005,10 @@ static int qc_parse_pkt_frms(struct quic_conn *qc, struct quic_rx_packet *pkt, if (!conn_id) break; + tree = &quic_cid_trees[quic_cid_tree_idx(&conn_id->cid)]; + HA_RWLOCK_WRLOCK(QC_CID_LOCK, &tree->lock); ebmb_delete(&conn_id->node); + HA_RWLOCK_WRUNLOCK(QC_CID_LOCK, &tree->lock); eb64_delete(&conn_id->seq_num); pool_free(pool_head_quic_connection_id, conn_id); TRACE_PROTO("CID retired", QUIC_EV_CONN_PSTRM, qc);