From 247590afab78c46ab1dc5fe804ec5b5daffd8934 Mon Sep 17 00:00:00 2001 From: jpk68 Date: Sat, 25 Jul 2026 11:34:36 -0400 Subject: [PATCH] chore: fix more memory safety issues --- libi2pd/Family.cpp | 2 +- libi2pd/Gzip.cpp | 1 + libi2pd/HTTP.cpp | 2 +- libi2pd/RouterInfo.cpp | 2 +- libi2pd/util.cpp | 2 ++ libi2pd_client/I2CP.cpp | 11 +++++++---- 6 files changed, 13 insertions(+), 7 deletions(-) diff --git a/libi2pd/Family.cpp b/libi2pd/Family.cpp index dcbf11e9..933eb6da 100644 --- a/libi2pd/Family.cpp +++ b/libi2pd/Family.cpp @@ -92,7 +92,7 @@ namespace data } for (const std::string & file : files) { - if (file.compare(file.size() - 4, 4, ".crt") != 0) { + if (file.size () < 4 || file.compare(file.size() - 4, 4, ".crt") != 0) { LogPrint(eLogWarning, "Family: ignoring file ", file); continue; } diff --git a/libi2pd/Gzip.cpp b/libi2pd/Gzip.cpp index 019b417b..526d414d 100644 --- a/libi2pd/Gzip.cpp +++ b/libi2pd/Gzip.cpp @@ -193,6 +193,7 @@ namespace data size_t GzipNoCompression (const std::vector >& bufs, uint8_t * out, size_t outLen) { static const uint8_t gzipHeader[11] = { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x01 }; + if (outLen < 23) return 0; memcpy (out, gzipHeader, 11); uint32_t crc = 0; size_t len = 0; diff --git a/libi2pd/HTTP.cpp b/libi2pd/HTTP.cpp index 036c1dde..e9951511 100644 --- a/libi2pd/HTTP.cpp +++ b/libi2pd/HTTP.cpp @@ -557,7 +557,7 @@ namespace http if (c == '%') { decoded.append (url, start, i - start); - if (i + 2 <= url.length ()) + if (i + 3 <= url.length ()) { unsigned char ch; auto res = std::from_chars(url.data() + i + 1, url.data() + i + 3, ch, 16); diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 0665b2fd..206daf82 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -93,7 +93,7 @@ namespace data } // verify signature since we have identity already int l = len - m_RouterIdentity->GetSignatureLen (); - if (m_RouterIdentity->Verify (buf, l, buf + l)) + if (l >= 0 && m_RouterIdentity->Verify (buf, l, buf + l)) { // clean up m_IsUpdated = true; diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index 52946206..65858389 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -261,6 +261,7 @@ namespace util std::string_view Mapping::ExtractString (const uint8_t * buf, size_t len) { + if (!len) return { }; uint8_t l = buf[0]; if (l > len) l = len; return { (const char *)(buf + 1), l }; @@ -282,6 +283,7 @@ namespace util size_t Mapping::WriteString (std::string_view str, uint8_t * buf, size_t len) { + if (!len) return 0; auto l = str.length (); if (l + 1 >= len) l = len - 1; if (l > 255) l = 255; // 1 byte max diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index 4bd60b19..9f6324bd 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -836,18 +836,21 @@ namespace client void I2CPSession::CreateLeaseSetMessageHandler (const uint8_t * buf, size_t len) { + size_t offset = 2 + i2p::crypto::DSA_PRIVATE_KEY_LENGTH + 256; + if (len < offset) + { + LogPrint (eLogError, "I2CP: CreateLeaseSetMessage is too short ", len); + return; + } uint16_t sessionID = bufbe16toh (buf); if (sessionID == m_SessionID) { - size_t offset = 2; if (m_Destination) { - offset += i2p::crypto::DSA_PRIVATE_KEY_LENGTH; // skip signing private key // we always assume this field as 20 bytes (DSA) regardless actual size // instead of //offset += m_Destination->GetIdentity ()->GetSigningPrivateKeyLen (); - m_Destination->SetEncryptionPrivateKey (i2p::data::CRYPTO_KEY_TYPE_ELGAMAL, buf + offset); - offset += 256; + m_Destination->SetEncryptionPrivateKey (i2p::data::CRYPTO_KEY_TYPE_ELGAMAL, buf + 2 + i2p::crypto::DSA_PRIVATE_KEY_LENGTH); m_Destination->LeaseSetCreated (buf + offset, len - offset); } }