diff options
author | Vasil Dimov <vd@FreeBSD.org> | 2021-03-10 12:07:08 +0100 |
---|---|---|
committer | Vasil Dimov <vd@FreeBSD.org> | 2021-03-16 11:00:57 +0100 |
commit | 80a5a8ea2b7ad512c74c29df5b504e9be6cf23a0 (patch) | |
tree | 4afdcf0bdbde9a1692073c09d5f66aa04efc3a5c /src/util/sock.cpp | |
parent | 7cdadf91d513250b983b6a1c4672a6acc0dcf074 (diff) |
i2p: limit the size of incoming messages
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.
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: { |