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