Commit 0376ea6b7f for openssl.org

commit 0376ea6b7f4c25dc8194387ea65336ad86b5759a
Author: Jakub Zelenka <jakub.zelenka@openssl.foundation>
Date:   Tue Sep 8 19:51:01 2026 +0200

    quic-radix: inject the path challenge flood only into 1-RTT packets

    check_pc_flood mounts a one shot mutator as soon as SSL_connect()
    returns and expects the next packet to carry the injected PATH_CHALLENGE
    frames. On a slow runner the client's Handshake PTO probe can go out
    first while HANDSHAKE_DONE is still in flight, so the injection lands in
    a Handshake packet that the server drops after confirming the handshake
    and check_flood_stats spins until the script deadline.

    Mutate only 1-RTT packets, which is the only place PATH_CHALLENGE is
    valid, and reset the one shot flag when the flood is mounted.

    Assisted-by: Claude:claude-fable-5-1
    Reviewed-by: Matt Caswell <matt@openssl.foundation>
    Reviewed-by: Saša NedvÄ›dický <sashan@openssl.org>
    Merge-date: Wed Sep 16 13:42:36 2026
    Merged-from: https://github.com/openssl/openssl/pull/32748

diff --git a/test/radix/quic_tests.c b/test/radix/quic_tests.c
index b6eaa5273e..848e46004d 100644
--- a/test/radix/quic_tests.c
+++ b/test/radix/quic_tests.c
@@ -663,8 +663,14 @@ static int mutcbk_inject_frames(const QUIC_PKT_HDR *hdrin,
      * packet send itself failed (tearing down the connection), so once
      * we're done mutating we must pass subsequent packets through
      * unmodified instead.
+     *
+     * PATH_CHALLENGE is only valid in 0-RTT and 1-RTT packets. The client can
+     * still send a Handshake packet after SSL_connect() returns, e.g. a PTO
+     * probe while HANDSHAKE_DONE is in flight, which the server drops once the
+     * handshake is confirmed. So only a 1-RTT packet is mutated and anything
+     * else passes through without consuming the one shot.
      */
-    if (mutctx->mutctx_done) {
+    if (mutctx->mutctx_done || hdrin->type != QUIC_PKT_TYPE_1RTT) {
         *hdrout = (QUIC_PKT_HDR *)hdrin;
         *iovecout = iovecin;
         *numout = numin;
@@ -777,6 +783,7 @@ DEF_FUNC(mount_flood)

     mutctx.mutctx_inject = inject_frames;
     mutctx.mutctx_inject_sz = sizeof(PATH_CHALLENGE_FRAMES) - 1;
+    mutctx.mutctx_done = 0;
     REQUIRE_SSL(ssl);
     ch = ossl_quic_conn_get_channel(ssl);
     if (!TEST_ptr(ch))