Make client drop packets with wrong versions
In Google QUIC, packets with the version flag set and a different version number were version negotiation packets. In IETF QUIC, version negotiation packets have their own format, and it is now possible for a client to receive a packet that is not a version negotiation packet but still has a version different from what it expects. Those packets must be dropped.
This issue was found by Chromium clusterfuzz:
https://bugs.chromium.org/p/chromium/issues/detail?id=959143
I was able to reproduce the fuzzer DCHECK failure and verify that the fix prevents it.
gfe-relnote: client-only change to handling of packets with invalid versions, not flag protected
PiperOrigin-RevId: 246921247
Change-Id: I6610c9cd8c667bfad62fd335cc7f45fc425d3d2e
diff --git a/quic/core/quic_framer_test.cc b/quic/core/quic_framer_test.cc
index 56665df..0b5dca5 100644
--- a/quic/core/quic_framer_test.cc
+++ b/quic/core/quic_framer_test.cc
@@ -12938,6 +12938,36 @@
ASSERT_EQ(visitor_.coalesced_packets_.size(), 0u);
}
+TEST_P(QuicFramerTest, ClientReceivesInvalidVersion) {
+ if (framer_.transport_version() < QUIC_VERSION_44) {
+ return;
+ }
+ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
+
+ // clang-format off
+ unsigned char packet[] = {
+ // public flags (long header with packet type INITIAL)
+ 0xFF,
+ // version that is different from the framer's version
+ 'Q', '0', '4', '3',
+ // connection ID lengths
+ 0x05,
+ // source connection ID
+ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+ // packet number
+ 0x01,
+ // padding frame
+ 0x00,
+ };
+ // clang-format on
+
+ QuicEncryptedPacket encrypted(AsChars(packet), QUIC_ARRAYSIZE(packet), false);
+ EXPECT_FALSE(framer_.ProcessPacket(encrypted));
+
+ EXPECT_EQ(QUIC_INVALID_VERSION, framer_.error());
+ EXPECT_EQ("Client received unexpected version.", framer_.detailed_error());
+}
+
TEST_P(QuicFramerTest, PacketHeaderWithVariableLengthConnectionId) {
if (framer_.transport_version() < QUIC_VERSION_46) {
return;