From 8921125924c5e95acaa284ff1a5bcb31430ff824 Mon Sep 17 00:00:00 2001 From: Stephen Shelton Date: Fri, 31 Jan 2020 14:48:00 -0700 Subject: [PATCH] Fix buffer overflow when version encodes too many integers --- llarp/router_version.cpp | 7 +++- test/router/test_llarp_router_version.cpp | 41 +++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/llarp/router_version.cpp b/llarp/router_version.cpp index 482a508a0..8c55aee29 100644 --- a/llarp/router_version.cpp +++ b/llarp/router_version.cpp @@ -63,11 +63,16 @@ namespace llarp uint64_t i; if(idx == 0) { - if(not bencode_read_integer(buffer, &self->m_ProtoVersion)) + uint64_t val = -1; + if(not bencode_read_integer(buffer, &val)) return false; + self->m_ProtoVersion = val; } else if(bencode_read_integer(buffer, &i)) { + // prevent overflow (note that idx includes version too) + if (idx > self->m_Version.max_size()) + return false; self->m_Version[idx - 1] = i; } else diff --git a/test/router/test_llarp_router_version.cpp b/test/router/test_llarp_router_version.cpp index b5913c48f..1f9e939cc 100644 --- a/test/router/test_llarp_router_version.cpp +++ b/test/router/test_llarp_router_version.cpp @@ -48,3 +48,44 @@ TEST_F(TestRouterVersion, TestClear) EXPECT_TRUE(version.IsEmpty()); } +TEST_F(TestRouterVersion, TestBEncode) +{ + llarp::RouterVersion v1235( {1, 2, 3}, 5); + + std::array< byte_t, 128 > tmp; + llarp_buffer_t buf(tmp); + + EXPECT_TRUE(v1235.BEncode(&buf)); + + std::string s((const char*)buf.begin(), (buf.end() - buf.begin())); + LogInfo("bencoded: ", buf.begin()); + + EXPECT_STREQ((const char*)buf.begin(), "li5ei1ei2ei3ee"); + +} + +TEST_F(TestRouterVersion, TestBDecode) +{ + llarp::RouterVersion version; + version.Clear(); + + const std::string bString("li9ei3ei2ei1ee"); + llarp_buffer_t buf(bString.data(), bString.size()); + EXPECT_TRUE(version.BDecode(&buf)); + + llarp::RouterVersion expected( {3, 2, 1}, 9); + + EXPECT_EQ(expected, version); + +} + +TEST_F(TestRouterVersion, TestDecodeLongVersionArray) +{ + llarp::RouterVersion version; + version.Clear(); + + const std::string bString("li9ei3ei2ei1ei2ei3ei4ei5ei6ei7ei8ei9ee"); + llarp_buffer_t buf(bString.data(), bString.size()); + EXPECT_FALSE(version.BDecode(&buf)); + +}