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.
This commit is contained in:
Vasil Dimov
2021-03-10 12:07:08 +01:00
parent 7cdadf91d5
commit 80a5a8ea2b
4 changed files with 22 additions and 5 deletions

View File

@@ -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: {