mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2026-08-29 09:48:47 +00:00
Merge pull request #2499 from jpk68/checks-2
libi2pd: add missing checks and limits
This commit is contained in:
@@ -654,6 +654,7 @@ namespace datagram
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_RoutingSession) return nullptr;
|
||||
auto path = m_RoutingSession->GetSharedRoutingPath();
|
||||
if (path && m_RoutingSession->IsRatchets () && m_RoutingSession->CleanupUnconfirmedTags ())
|
||||
{
|
||||
|
||||
@@ -557,8 +557,19 @@ namespace client
|
||||
|
||||
void LeaseSetDestination::HandleDatabaseSearchReplyMessage (const uint8_t * buf, size_t len)
|
||||
{
|
||||
if (len < 33)
|
||||
{
|
||||
LogPrint (eLogWarning, "Destination: Database search reply is too short, ", len);
|
||||
return;
|
||||
}
|
||||
i2p::data::IdentHash key (buf);
|
||||
int num = buf[32]; // num
|
||||
size_t maxNum = (len - 33)/32;
|
||||
if ((size_t)num > maxNum)
|
||||
{
|
||||
LogPrint (eLogWarning, "Destination: Declared number of peer hashes ", num, " exceeds message size, reduced to ", maxNum);
|
||||
num = maxNum;
|
||||
}
|
||||
LogPrint (eLogDebug, "Destination: DatabaseSearchReply for ", key.ToBase64 (), " num=", num);
|
||||
auto it = m_LeaseSetRequests.find (key);
|
||||
if (it != m_LeaseSetRequests.end ())
|
||||
|
||||
+1
-1
@@ -992,7 +992,7 @@ namespace transport
|
||||
return;
|
||||
}
|
||||
auto size = bufbe16toh (buf->data () + 1);
|
||||
if (size + 3 > (int)buf->size () || size > i2p::data::MAX_RI_BUFFER_SIZE + 1)
|
||||
if (size < 1 || size + 3 > (int)buf->size () || size > i2p::data::MAX_RI_BUFFER_SIZE + 1)
|
||||
{
|
||||
LogPrint (eLogError, "NTCP2: Unexpected RouterInfo size ", size, " in SessionConfirmed");
|
||||
boost::asio::post (m_Server.GetService (), std::bind (&NTCP2Session::Terminate, shared_from_this ()));
|
||||
|
||||
@@ -360,6 +360,12 @@ namespace data
|
||||
void NetDbRequests::HandleDatabaseSearchReplyMsg (std::shared_ptr<const I2NPMessage> msg)
|
||||
{
|
||||
const uint8_t * buf = msg->GetPayload ();
|
||||
size_t payloadLen = msg->GetPayloadLength ();
|
||||
if (payloadLen < 33)
|
||||
{
|
||||
LogPrint (eLogWarning, "NetDbReq: Database search reply is too short, ", payloadLen);
|
||||
return;
|
||||
}
|
||||
std::string key;
|
||||
size_t num = buf[32]; // num
|
||||
if (CheckLogLevel (eLogInfo))
|
||||
@@ -393,7 +399,13 @@ namespace data
|
||||
{
|
||||
LogPrint (eLogWarning, "NetDbReq: Too many peer hashes ", num, " in database search reply, Reduced to ", NETDB_MAX_NUM_SEARCH_REPLY_PEER_HASHES);
|
||||
num = NETDB_MAX_NUM_SEARCH_REPLY_PEER_HASHES;
|
||||
}
|
||||
}
|
||||
size_t maxNum = (payloadLen - 33)/32;
|
||||
if (num > maxNum)
|
||||
{
|
||||
LogPrint (eLogWarning, "NetDbReq: Declared number of peer hashes ", num, " exceeds message size, reduced to ", maxNum);
|
||||
num = maxNum;
|
||||
}
|
||||
if (isExploratory && !m_DiscoveredRouterHashes.empty ())
|
||||
{
|
||||
// request outstanding routers
|
||||
|
||||
@@ -36,6 +36,8 @@ namespace i2p
|
||||
{
|
||||
namespace data
|
||||
{
|
||||
const uint64_t MAX_RESEED_CONTENT_LENGTH = 128*1024*1024; // 128 MB, sanity cap for SU3 content length
|
||||
const uint32_t MAX_RESEED_FILE_SIZE = 64*1024*1024; // 64 MB, sanity cap for a single file inside the SU3 zip
|
||||
|
||||
Reseeder::Reseeder()
|
||||
{
|
||||
@@ -231,6 +233,11 @@ namespace data
|
||||
uint64_t contentLength;
|
||||
s.read ((char *)&contentLength, 8); // content length
|
||||
contentLength = be64toh (contentLength);
|
||||
if (contentLength > MAX_RESEED_CONTENT_LENGTH)
|
||||
{
|
||||
LogPrint (eLogError, "Reseed: SU3 content length too large: ", contentLength);
|
||||
return 0;
|
||||
}
|
||||
s.seekg (1, std::ios::cur); // unused
|
||||
uint8_t fileType;
|
||||
s.read ((char *)&fileType, 1); // file type
|
||||
@@ -387,6 +394,11 @@ namespace data
|
||||
LogPrint (eLogWarning, "Reseed: Unexpected size 0. Skipped");
|
||||
continue;
|
||||
}
|
||||
if (compressedSize > MAX_RESEED_FILE_SIZE || uncompressedSize > MAX_RESEED_FILE_SIZE)
|
||||
{
|
||||
LogPrint (eLogError, "Reseed: SU3 file size too large, compressed=", compressedSize, " uncompressed=", uncompressedSize);
|
||||
return numFiles;
|
||||
}
|
||||
|
||||
uint8_t * compressed = new uint8_t[compressedSize];
|
||||
s.read ((char *)compressed, compressedSize);
|
||||
|
||||
@@ -450,8 +450,9 @@ namespace stream
|
||||
bool Stream::ProcessOptions (uint16_t flags, Packet * packet)
|
||||
{
|
||||
const uint8_t * optionData = packet->GetOptionData ();
|
||||
size_t optionOffset = optionData - packet->buf;
|
||||
size_t optionSize = packet->GetOptionSize ();
|
||||
if (optionSize > packet->len)
|
||||
if (optionOffset > packet->len || optionSize > packet->len - optionOffset)
|
||||
{
|
||||
LogPrint (eLogInfo, "Streaming: Invalid option size ", optionSize, " Discarded");
|
||||
return false;
|
||||
@@ -626,8 +627,14 @@ namespace stream
|
||||
|
||||
if (flags & PACKET_FLAG_SIGNATURE_INCLUDED)
|
||||
{
|
||||
if (!m_TransientVerifier && !m_RemoteIdentity)
|
||||
{
|
||||
LogPrint (eLogError, "Streaming: Signature included without remote identity");
|
||||
return false;
|
||||
}
|
||||
auto signatureLen = m_TransientVerifier ? m_TransientVerifier->GetSignatureLen () : m_RemoteIdentity->GetSignatureLen ();
|
||||
if (signatureLen > packet->GetLength ())
|
||||
size_t optionOffset2 = optionData - packet->buf;
|
||||
if (optionOffset2 > packet->len || signatureLen > packet->len - optionOffset2)
|
||||
{
|
||||
LogPrint (eLogError, "Streaming: Signature too big, ", signatureLen, " bytes");
|
||||
return false;
|
||||
|
||||
@@ -628,13 +628,16 @@ namespace client
|
||||
if (!pos) // start of line
|
||||
{
|
||||
pos = line.find (" ");
|
||||
pos++;
|
||||
pos = line.find (" ", pos);
|
||||
pos++;
|
||||
auto nextpos = line.find (" ", pos);
|
||||
m_OutPacket << line.substr (0, pos);
|
||||
m_OutPacket << context.GetAddressBook ().ToAddress (m_From->GetIdentHash ());
|
||||
m_OutPacket << line.substr (nextpos) << '\n';
|
||||
if (pos != std::string::npos) pos = line.find (" ", pos + 1);
|
||||
auto nextpos = (pos != std::string::npos) ? line.find (" ", pos + 1) : std::string::npos;
|
||||
if (pos == std::string::npos || nextpos == std::string::npos)
|
||||
m_OutPacket << line << '\n'; // malformed USER line, pass through unmodified
|
||||
else
|
||||
{
|
||||
m_OutPacket << line.substr (0, pos + 1);
|
||||
m_OutPacket << context.GetAddressBook ().ToAddress (m_From->GetIdentHash ());
|
||||
m_OutPacket << line.substr (nextpos) << '\n';
|
||||
}
|
||||
}
|
||||
else
|
||||
m_OutPacket << line << '\n';
|
||||
|
||||
+11
-3
@@ -1310,9 +1310,17 @@ namespace client
|
||||
{
|
||||
// get remote peer address
|
||||
auto dest = stream->GetRemoteIdentity()->ToBase64 ();
|
||||
memcpy (newSocket->m_StreamBuffer, dest.c_str (), dest.length ());
|
||||
newSocket->m_StreamBuffer[dest.length ()] = '\n';
|
||||
newSocket->HandleI2PReceive (boost::system::error_code (),dest.length () + 1); // we send identity like it has been received from stream
|
||||
if (dest.length () + 1 > SAM_STREAM_BUFFER_SIZE)
|
||||
{
|
||||
LogPrint (eLogError, "SAM: Remote identity is too long ", dest.length ());
|
||||
newSocket->TerminateClose ();
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy (newSocket->m_StreamBuffer, dest.c_str (), dest.length ());
|
||||
newSocket->m_StreamBuffer[dest.length ()] = '\n';
|
||||
newSocket->HandleI2PReceive (boost::system::error_code (),dest.length () + 1); // we send identity like it has been received from stream
|
||||
}
|
||||
}
|
||||
else
|
||||
newSocket->I2PReceive ();
|
||||
|
||||
Reference in New Issue
Block a user