From 794d068d8fbe37fe6fb4803c52ae01544f9f0139 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= Date: Thu, 27 Jan 2022 10:23:31 +0100 Subject: [PATCH] MINOR: proto_quic: Wrong allocations for TX rings and RX bufs As mentionned in the comment, the tx_qrings and rxbufs members of receiver struct must be pointers to pointers! Modify the functions responsible of their allocations consequently. Note that this code could work because sizeof rxbuf and sizeof tx_qrings are greater than the size of pointer! --- include/haproxy/receiver-t.h | 6 +++--- src/proto_quic.c | 31 +++++++++++++++++++++++++------ 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/include/haproxy/receiver-t.h b/include/haproxy/receiver-t.h index 91a6ea2ea..83ac04953 100644 --- a/include/haproxy/receiver-t.h +++ b/include/haproxy/receiver-t.h @@ -68,11 +68,11 @@ struct receiver { struct eb_root odcids; /* QUIC original destination connection IDs. */ struct eb_root cids; /* QUIC connection IDs. */ __decl_thread(HA_RWLOCK_T cids_lock); /* RW lock for connection IDs tree accesses */ - struct qring *tx_qrings; /* Array of rings (one by thread) */ - struct mt_list tx_qring_list; /* The same as ->qrings but arranged in a list */ + struct qring **tx_qrings; /* Array of rings (one by thread) */ + struct mt_list tx_qring_list; /* The same as ->tx_qrings but arranged in a list */ struct quic_dghdlr **dghdlrs; /* Datagram handlers (one by thread) */ - struct rxbuf *rxbufs; /* Array of buffers for RX (one by thread) */ + struct rxbuf **rxbufs; /* Array of buffers for RX (one by thread) */ struct mt_list rxbuf_list; /* The same as ->rxbufs but arranged in a list */ #endif /* warning: this struct is huge, keep it at the bottom */ diff --git a/src/proto_quic.c b/src/proto_quic.c index f7f9f7d6d..99b8afdff 100644 --- a/src/proto_quic.c +++ b/src/proto_quic.c @@ -543,18 +543,26 @@ static int quic_alloc_tx_rings_listener(struct listener *l) MT_LIST_INIT(&l->rx.tx_qring_list); for (i = 0; i < global.nbthread; i++) { unsigned char *buf; - struct qring *qr = &l->rx.tx_qrings[i]; + struct qring *qr; + + qr = calloc(1, sizeof *qr); + if (!qr) + goto err; buf = pool_alloc(pool_head_quic_tx_ring); - if (!buf) + if (!buf) { + free(qr); goto err; + } qr->cbuf = cbuf_new(buf, QUIC_TX_RING_BUFSZ); if (!qr->cbuf) { pool_free(pool_head_quic_tx_ring, buf); + free(qr); goto err; } + l->rx.tx_qrings[i] = qr; MT_LIST_APPEND(&l->rx.tx_qring_list, &qr->mt_list); } @@ -564,6 +572,7 @@ static int quic_alloc_tx_rings_listener(struct listener *l) while ((qr = MT_LIST_POP(&l->rx.tx_qring_list, typeof(qr), mt_list))) { pool_free(pool_head_quic_tx_ring, qr->cbuf->buf); cbuf_free(qr->cbuf); + free(qr); } free(l->rx.tx_qrings); return 0; @@ -584,12 +593,20 @@ static int quic_alloc_rxbufs_listener(struct listener *l) MT_LIST_INIT(&l->rx.rxbuf_list); for (i = 0; i < global.nbthread; i++) { char *buf; + struct rxbuf *rxbuf; - rxbuf = &l->rx.rxbufs[i]; - buf = pool_alloc(pool_head_quic_rxbuf); - if (!buf) + rxbuf = calloc(1, sizeof *rxbuf); + if (!rxbuf) goto err; + buf = pool_alloc(pool_head_quic_rxbuf); + if (!buf) { + free(rxbuf); + goto err; + } + + l->rx.rxbufs[i] = rxbuf; + rxbuf->buf = b_make(buf, QUIC_RX_BUFSZ, 0, 0); LIST_INIT(&rxbuf->dgrams); MT_LIST_APPEND(&l->rx.rxbuf_list, &rxbuf->mt_list); @@ -598,8 +615,10 @@ static int quic_alloc_rxbufs_listener(struct listener *l) return 1; err: - while ((rxbuf = MT_LIST_POP(&l->rx.rxbuf_list, typeof(rxbuf), mt_list))) + while ((rxbuf = MT_LIST_POP(&l->rx.rxbuf_list, typeof(rxbuf), mt_list))) { pool_free(pool_head_quic_rxbuf, rxbuf->buf.area); + free(rxbuf); + } free(l->rx.rxbufs); return 0; }