]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MINOR: quic: late packets of the first key phase are dropped
authorFrederic Lecaille <flecaille@haproxy.com>
Mon, 31 Aug 2026 14:53:48 +0000 (16:53 +0200)
committerFrederic Lecaille <flecaille@haproxy.com>
Mon, 31 Aug 2026 16:33:17 +0000 (18:33 +0200)
qc_pkt_decrypt() tests <qc->ku.prv_rx.pn> to know whether the previous key
phase secrets are usable. This number comes from <tls_ctx->rx.pn>, which is
only set on a key phase change and is thus still 0 during the first key phase.
After the first key update the test always fails and every late packet of the
initial key phase is dropped instead of being decrypted with the previous keys.

Test <qc->ku.prv_rx.ctx> instead: it is NULL before the first key update, and
set after it.

This bug was introduced by commit a7d2c0946 ("MINOR: quic: Enable the Key
Update process").

This must be backported as far as 2.6.

src/quic_rx.c

index afdba0ce0f2ef047fb304343fb6b6dfaf9a43fb3..bff7f1d96a47e6adc916c11c96b80c652eab10f2 100644 (file)
@@ -146,13 +146,11 @@ static int qc_pkt_decrypt(struct quic_conn *qc, struct quic_enc_level *qel,
                 */
                if (!(*pkt->data & QUIC_PACKET_KEY_PHASE_BIT) ^ !(tls_ctx->flags & QUIC_FL_TLS_KP_BIT_SET)) {
                        if (pkt->pn < tls_ctx->rx.pn) {
-                               /* The lowest packet number of a previous key phase
-                                * cannot be null if it really stores previous key phase
-                                * secrets.
+                               /* The previous key phase secrets are only
+                                * available after a first key update.
                                 */
-                               // TODO: check if BUG_ON() more suitable
-                               if (!qc->ku.prv_rx.pn) {
-                                       TRACE_ERROR("null previous packet number", QUIC_EV_CONN_RXPKT, qc);
+                               if (!qc->ku.prv_rx.ctx) {
+                                       TRACE_ERROR("no previous key phase secrets", QUIC_EV_CONN_RXPKT, qc);
                                        goto leave;
                                }