From 966963ac7d62bdac051eacae234495fd355919e6 Mon Sep 17 00:00:00 2001 From: deadbeef Date: Mon, 8 May 2017 11:35:56 -0700 Subject: [PATCH] Fixing invalid IPv6 address parsing stack underflow on Windows. Occurred when parsing an address with more than 7 colons. For example: 1::2:3:4:5:6:7::8 BUG=webrtc:7592 Review-Url: https://codereview.webrtc.org/2867653002 Cr-Commit-Position: refs/heads/master@{#18054} --- webrtc/base/win32.cc | 7 ++++++- webrtc/base/win32_unittest.cc | 27 +++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/webrtc/base/win32.cc b/webrtc/base/win32.cc index 485f7a6931..89970ec3a9 100644 --- a/webrtc/base/win32.cc +++ b/webrtc/base/win32.cc @@ -276,6 +276,11 @@ int inet_pton_v6(const char* src, void* dst) { ++coloncounter; } // (coloncount + 1) is the number of shorts left in the address. + // If this number is greater than the number of available shorts, the + // address is malformed. + if (coloncount + 1 > addr_end - addr_cursor) { + return 0; + } addr_cursor = addr_end - (coloncount + 1); seencompressed = true; } @@ -285,7 +290,7 @@ int inet_pton_v6(const char* src, void* dst) { } else { uint16_t word; int bytesread = 0; - if (sscanf(readcursor, "%hx%n", &word, &bytesread) != 1) { + if (sscanf(readcursor, "%4hx%n", &word, &bytesread) != 1) { return 0; } else { *addr_cursor = HostToNetwork16(word); diff --git a/webrtc/base/win32_unittest.cc b/webrtc/base/win32_unittest.cc index 15b2614111..96e0bd292a 100644 --- a/webrtc/base/win32_unittest.cc +++ b/webrtc/base/win32_unittest.cc @@ -92,4 +92,31 @@ TEST_F(Win32Test, IPv6AddressCompression) { EXPECT_EQ("1234:5678:abcd:1234:5678:abcd:1234:5678", ipv6.ToString()); } +// Test that invalid IPv6 addresses are recognized and false is returned. +TEST_F(Win32Test, InvalidIPv6AddressParsing) { + IPAddress ipv6; + + // More than 1 run of "::"s. + EXPECT_FALSE(IPFromString("1::2::3", &ipv6)); + + // More than 1 run of "::"s in a longer address. + // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=7592 + EXPECT_FALSE(IPFromString("1::2::3::4::5::6::7::8", &ipv6)); + + // Three ':'s in a row. + EXPECT_FALSE(IPFromString("1:::2", &ipv6)); + + // Non-hex character. + EXPECT_FALSE(IPFromString("test::1", &ipv6)); + + // More than 4 hex digits per group. + EXPECT_FALSE(IPFromString("abcde::1", &ipv6)); + + // More than 8 groups. + EXPECT_FALSE(IPFromString("1:2:3:4:5:6:7:8:9", &ipv6)); + + // Less than 8 groups. + EXPECT_FALSE(IPFromString("1:2:3:4:5:6:7", &ipv6)); +} + } // namespace rtc