From: William Dauchy Date: Thu, 12 Nov 2026 16:50:46 +0000 (+0100) Subject: BUG/MINOR: quic-be: drop long header packets with unsupported version X-Git-Tag: v3.5-dev12~23 X-Git-Url: https://git.kaiwu.me/%7B@url%7D?a=commitdiff_plain;h=f12c7c7d9f0d0b7880d021924d2f056d1303fe05;p=haproxy.git BUG/MINOR: quic-be: drop long header packets with unsupported version On backend connections, quic_rx_pkt_parse() accepts long header packets with an unsupported version and Version Negotiation packets, as these checks only apply to listeners. Such packets keep the QUIC_PACKET_TYPE_UNKNOWN type, which maps to no encryption level, and hit BUG_ON(!qel || !pktns) in qc_enc_level_alloc() from qc_try_rm_hp(), or a NULL dereference without DEBUG_STRICT. No malicious peer is required: a server which does not support the version selected by haproxy responds with a Version Negotiation packet (RFC 9000 6.1). A malicious server or an on-path attacker may also send a packet with an unsupported version. Drop these packets on backend connections, as required by RFC 9000 5.2.1, since version negotiation is not supported on the backend side. To do so, export quic_version_VN_reserved and compare the packet version to it instead of testing a null version number. This should be backported up to 3.3, where it was introduced by 43d88a44f ("MINOR: quic-be: Datagrams and packet parsing support"). Signed-off-by: William Dauchy --- diff --git a/include/haproxy/quic_conn-t.h b/include/haproxy/quic_conn-t.h index 9870c9938..3b84b2db1 100644 --- a/include/haproxy/quic_conn-t.h +++ b/include/haproxy/quic_conn-t.h @@ -222,6 +222,7 @@ extern const struct quic_version *preferred_version; extern const struct quic_version *quic_version_draft_29; extern const struct quic_version *quic_version_1; extern const struct quic_version *quic_version_2; +extern const struct quic_version quic_version_VN_reserved; /* unused: 0x01 */ /* Flag the packet number space as requiring an ACK frame to be sent. */ diff --git a/src/quic_rx.c b/src/quic_rx.c index 657269e6b..e295ab928 100644 --- a/src/quic_rx.c +++ b/src/quic_rx.c @@ -2104,6 +2104,12 @@ static int quic_rx_pkt_parse(struct quic_conn *qc, struct quic_rx_packet *pkt, goto drop_silent; } + if (!l && (!pkt->version || pkt->version == &quic_version_VN_reserved)) { + TRACE_PROTO("RX unsupported version or VN packet on backend", + QUIC_EV_CONN_LPKT, NULL, NULL, NULL, pkt->version); + goto drop; + } + if (pkt->type == QUIC_PACKET_TYPE_INITIAL) { /* For Initial packets, and for servers (QUIC clients connections), * there is no Initial connection IDs storage.