]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MAJOR: quic: remove qc from receiver cids tree on free
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 30 Sep 2021 09:03:28 +0000 (11:03 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 7 Oct 2021 15:35:25 +0000 (17:35 +0200)
Remove the quic_conn from the receiver connection_ids tree on
quic_conn_free. This fixes a crash due to dangling references in the
tree after a quic connection release.

This operation must be conducted under the listener lock. For this
reason, the quic_conn now contains a reference to its attached listener.

include/haproxy/xprt_quic-t.h
src/xprt_quic.c

index 6e83594debfac0a3fcbb9d2b9b91945ed7f08100..9e282f5d5ea0eea8cb9ed68d494b5322f900137f 100644 (file)
@@ -657,6 +657,7 @@ struct quic_conn {
        struct quic_path paths[1];
        struct quic_path *path;
 
+       struct listener *li; /* only valid for frontend connections */
        /* MUX */
        struct qcc *qcc;
        struct task *timer_task;
index cee93229ef26aa3f63ae5fa3617bf5c2bb26fb67..3fd46328483b21ac4421862d48d1777c6918651e 100644 (file)
@@ -2903,6 +2903,13 @@ static void quic_conn_free(struct quic_conn *conn)
                return;
 
        free_quic_conn_cids(conn);
+
+       /* remove the connection from receiver cids trees */
+       HA_RWLOCK_WRLOCK(OTHER_LOCK, &conn->li->rx.cids_lock);
+       ebmb_delete(&conn->odcid_node);
+       ebmb_delete(&conn->scid_node);
+       HA_RWLOCK_WRUNLOCK(OTHER_LOCK, &conn->li->rx.cids_lock);
+
        for (i = 0; i < QUIC_TLS_ENC_LEVEL_MAX; i++)
                quic_conn_enc_level_uninit(&conn->els[i]);
        if (conn->timer_task)
@@ -3004,6 +3011,7 @@ static struct quic_conn *qc_new_conn(unsigned int version, int ipv4,
                        memcpy(qc->dcid.data, scid, scid_len);
                qc->dcid.len = scid_len;
                qc->tx.qring_list = &l->rx.tx_qrings;
+               qc->li = l;
        }
        /* QUIC Client (outgoing connection to servers) */
        else {