diff options
author | Wladimir J. van der Laan <laanwj@protonmail.com> | 2021-03-16 13:07:52 +0100 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@protonmail.com> | 2021-03-16 13:11:59 +0100 |
commit | 1b6c463e033f861561d1a46ccf7eec069bbac09f (patch) | |
tree | a6175ed1a96ea54a5cfd275503ed6ffb65e9039a /src/test | |
parent | 77234793004a757426f67389d09bcee502033aa1 (diff) | |
parent | 7059e6d82275b44efc41675ee10760145b6c1073 (diff) |
Merge #21407: i2p: limit the size of incoming messages
7059e6d82275b44efc41675ee10760145b6c1073 test: add a test to ensure RecvUntilTerminator() limit works (Vasil Dimov)
80a5a8ea2b7ad512c74c29df5b504e9be6cf23a0 i2p: limit the size of incoming messages (Vasil Dimov)
Pull request description:
Put a limit on the amount of data `Sock::RecvUntilTerminator()` can read
if no terminator is received.
In the case of I2P this avoids a runaway (or malicious) I2P proxy
sending us tons of data without a terminator before a timeout is
triggered.
ACKs for top commit:
laanwj:
Re-ACK 7059e6d82275b44efc41675ee10760145b6c1073
Tree-SHA512: 21f3f3468c765c726cdc877eae847cdb4dbe225d94c5bd1849bd752c9761fac881c554f16ea7a685ad40312159d554e126c481e21c5fd83a6d947060b920373d
Diffstat (limited to 'src/test')
-rw-r--r-- | src/test/sock_tests.cpp | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/src/test/sock_tests.cpp b/src/test/sock_tests.cpp index ed9780dfb5..400de875b7 100644 --- a/src/test/sock_tests.cpp +++ b/src/test/sock_tests.cpp @@ -4,11 +4,13 @@ #include <compat.h> #include <test/util/setup_common.h> +#include <threadinterrupt.h> #include <util/sock.h> #include <util/system.h> #include <boost/test/unit_test.hpp> +#include <cassert> #include <thread> using namespace std::chrono_literals; @@ -144,6 +146,35 @@ BOOST_AUTO_TEST_CASE(wait) waiter.join(); } +BOOST_AUTO_TEST_CASE(recv_until_terminator_limit) +{ + constexpr auto timeout = 1min; // High enough so that it is never hit. + CThreadInterrupt interrupt; + int s[2]; + CreateSocketPair(s); + + Sock sock_send(s[0]); + Sock sock_recv(s[1]); + + std::thread receiver([&sock_recv, &timeout, &interrupt]() { + constexpr size_t max_data{10}; + bool threw_as_expected{false}; + // BOOST_CHECK_EXCEPTION() writes to some variables shared with the main thread which + // creates a data race. So mimic it manually. + try { + sock_recv.RecvUntilTerminator('\n', timeout, interrupt, max_data); + } catch (const std::runtime_error& e) { + threw_as_expected = HasReason("too many bytes without a terminator")(e); + } + assert(threw_as_expected); + }); + + BOOST_REQUIRE_NO_THROW(sock_send.SendComplete("1234567", timeout, interrupt)); + BOOST_REQUIRE_NO_THROW(sock_send.SendComplete("89a\n", timeout, interrupt)); + + receiver.join(); +} + #endif /* WIN32 */ BOOST_AUTO_TEST_SUITE_END() |