Skip to content

Commit 2c351df

Browse files
committed
BUG/MEDIUM: quic: CRYPTO frame freeing without eb_delete()
Since this commit: BUG/MINOR: quic: reorder fragmented RX CRYPTO frames by their offsets when they are parsed, the CRYPTO frames are ordered by their offsets into an ebtree. Then their data are provided to the ncbufs. But in case of error, when qc_handle_crypto_frm() returns QUIC_RX_RET_FRM_FATAL or QUIC_RX_RET_FRM_AGAIN), they remain attached to their tree. Then from <err> label, they are deteleted and deleted (with a while(node) { eb_delete(); qc_frm_free();} loop). But before this loop, these statements directly free the frame without deleting it from its tree, if this is a CRYPTO frame, leading to a use after free when running the loop: if (frm) qc_frm_free(qc, &frm); This issue was detected by the interop tests, with quic-go as client. Weirdly, this client sends CRYPTO frames by packet with holes. Must be backported as far as 2.6 as the commit mentioned above.
1 parent 01fcacf commit 2c351df

File tree

1 file changed

+4
-0
lines changed

1 file changed

+4
-0
lines changed

src/quic_conn.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3508,10 +3508,14 @@ static int qc_parse_pkt_frms(struct quic_conn *qc, struct quic_rx_packet *pkt,
35083508
ret = qc_handle_crypto_frm(qc, &frm->crypto, pkt, qel);
35093509
switch (ret) {
35103510
case QUIC_RX_RET_FRM_FATAL:
3511+
/* avoid freeing without eb_delete() */
3512+
frm = NULL;
35113513
goto err;
35123514

35133515
case QUIC_RX_RET_FRM_AGAIN:
35143516
TRACE_STATE("AGAIN encountered", QUIC_EV_CONN_PRSHPKT, qc);
3517+
/* avoid freeing without eb_delete() */
3518+
frm = NULL;
35153519
goto err;
35163520

35173521
case QUIC_RX_RET_FRM_DONE:

0 commit comments

Comments
 (0)