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/util/sock.cpp | |
parent | 77234793004a757426f67389d09bcee502033aa1 (diff) | |
parent | 7059e6d82275b44efc41675ee10760145b6c1073 (diff) | |
download | bitcoin-1b6c463e033f861561d1a46ccf7eec069bbac09f.tar.xz |
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/util/sock.cpp')
-rw-r--r-- | src/util/sock.cpp | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/src/util/sock.cpp b/src/util/sock.cpp index e13c52a16a..f9ecfef5d4 100644 --- a/src/util/sock.cpp +++ b/src/util/sock.cpp @@ -175,7 +175,8 @@ void Sock::SendComplete(const std::string& data, std::string Sock::RecvUntilTerminator(uint8_t terminator, std::chrono::milliseconds timeout, - CThreadInterrupt& interrupt) const + CThreadInterrupt& interrupt, + size_t max_data) const { const auto deadline = GetTime<std::chrono::milliseconds>() + timeout; std::string data; @@ -190,9 +191,14 @@ std::string Sock::RecvUntilTerminator(uint8_t terminator, // at a time is about 50 times slower. for (;;) { + if (data.size() >= max_data) { + throw std::runtime_error( + strprintf("Received too many bytes without a terminator (%u)", data.size())); + } + char buf[512]; - const ssize_t peek_ret{Recv(buf, sizeof(buf), MSG_PEEK)}; + const ssize_t peek_ret{Recv(buf, std::min(sizeof(buf), max_data - data.size()), MSG_PEEK)}; switch (peek_ret) { case -1: { |