Reject IETF RETRY packets before they hit QUIC_BUGs gfe-relnote: Fix QUIC framer bugs protected behind QUIC_VERSION_99, quic_supports_tls_handshake, and other QUIC flags This is expected to fix crbug.com/952581 PiperOrigin-RevId: 244394240 Change-Id: I8b4ad2af67f690db5c12fb902277a324a63ae244
diff --git a/quic/core/quic_framer.cc b/quic/core/quic_framer.cc index 0c65dc2..cc10cca 100644 --- a/quic/core/quic_framer.cc +++ b/quic/core/quic_framer.cc
@@ -2514,6 +2514,12 @@ set_detailed_error("Illegal long header type value."); return false; } + if (header->long_packet_type == RETRY && + (version().KnowsWhichDecrypterToUse() || + supports_multiple_packet_number_spaces_)) { + set_detailed_error("Not yet supported IETF RETRY packet received."); + return RaiseError(QUIC_INVALID_PACKET_HEADER); + } header->packet_number_length = GetLongHeaderPacketNumberLength( header->version.transport_version, type); }
diff --git a/quic/core/quic_framer_test.cc b/quic/core/quic_framer_test.cc index 2ffe54e..df72916 100644 --- a/quic/core/quic_framer_test.cc +++ b/quic/core/quic_framer_test.cc
@@ -13341,6 +13341,61 @@ &framer_, APPLICATION_DATA)); } +TEST_P(QuicFramerTest, IetfRetryPacketRejected) { + if (!framer_.version().KnowsWhichDecrypterToUse()) { + return; + } + + // clang-format off + PacketFragments packet = { + // public flags (IETF Retry packet, 0-length original destination CID) + {"Unable to read type.", + {0xf0}}, + // version tag + {"Unable to read protocol version.", + {QUIC_VERSION_BYTES}}, + // connection_id length + {"Not yet supported IETF RETRY packet received.", + {0x00}}, + }; + // clang-format on + + std::unique_ptr<QuicEncryptedPacket> encrypted( + AssemblePacketFromFragments(packet)); + + EXPECT_FALSE(framer_.ProcessPacket(*encrypted)); + EXPECT_EQ(QUIC_INVALID_PACKET_HEADER, framer_.error()); + CheckFramingBoundaries(packet, QUIC_INVALID_PACKET_HEADER); +} + +TEST_P(QuicFramerTest, RetryPacketRejectedWithMultiplePacketNumberSpaces) { + if (framer_.transport_version() < QUIC_VERSION_46) { + return; + } + framer_.EnableMultiplePacketNumberSpacesSupport(); + + // clang-format off + PacketFragments packet = { + // public flags (IETF Retry packet, 0-length original destination CID) + {"Unable to read type.", + {0xf0}}, + // version tag + {"Unable to read protocol version.", + {QUIC_VERSION_BYTES}}, + // connection_id length + {"Not yet supported IETF RETRY packet received.", + {0x00}}, + }; + // clang-format on + + std::unique_ptr<QuicEncryptedPacket> encrypted( + AssemblePacketFromFragments(packet)); + + EXPECT_FALSE(framer_.ProcessPacket(*encrypted)); + EXPECT_EQ(QUIC_INVALID_PACKET_HEADER, framer_.error()); + CheckFramingBoundaries(packet, QUIC_INVALID_PACKET_HEADER); +} + } // namespace } // namespace test } // namespace quic