From 1dc2e579f43a3cb81fca5ff9f438e37f288ed25a Mon Sep 17 00:00:00 2001 From: Lunar Date: Sat, 28 Feb 2026 23:27:21 +1000 Subject: [PATCH] add null check for netdb.NewIdentity and check offset > len to ensure nothing bad happens --- libi2pd/LeaseSet.cpp | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 3001bdfb..3debd06c 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -281,7 +281,7 @@ namespace data LogPrint (eLogError, "LeaseSet2: Actual buffer size ", int(len) , " exceeds full buffer size ", int(m_BufferLen)); } - LeaseSet2::LeaseSet2 (uint8_t storeType, const uint8_t * buf, size_t len, + LeaseSet2::LeaseSet2 (uint8_t storeType, const uint8_t * buf, size_t len, bool storeLeases, std::shared_ptr dest, CryptoKeyType preferredCrypto): LeaseSet (storeLeases), m_StoreType (storeType), m_EncryptionType (preferredCrypto) { @@ -321,6 +321,7 @@ namespace data if (readIdentity || !GetIdentity ()) { identity = netdb.NewIdentity (buf, len); + if (!identity) return; SetIdentity (identity); } else @@ -349,6 +350,7 @@ namespace data } // type specific part size_t s = 0; + if (offset > len) return; switch (m_StoreType) { case NETDB_STORE_TYPE_STANDARD_LEASESET2: @@ -418,8 +420,8 @@ namespace data // we pick max key type if preferred not found #if !OPENSSL_PQ if (keyType <= i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) // skip PQ keys if not supported -#endif - { +#endif + { if ((keyType == preferredKeyType || !m_Encryptor || keyType > m_EncryptionType) && (!dest || dest->SupportsEncryptionType (keyType))) { @@ -429,9 +431,9 @@ namespace data m_Encryptor = encryptor; // TODO: atomic m_EncryptionType = keyType; if (keyType == preferredKeyType) preferredKeyFound = true; - } + } } - } + } } offset += encryptionKeyLen; } @@ -443,12 +445,12 @@ namespace data { LogPrint (eLogWarning, "LeaseSet2: Expiration time is from future ", GetExpirationTime ()/1000LL); return 0; - } + } if (ts > m_PublishedTimestamp*1000LL + LEASESET_EXPIRATION_TIME_THRESHOLD) { LogPrint (eLogWarning, "LeaseSet2: Published time is too old ", m_PublishedTimestamp); return 0; - } + } if (IsStoreLeases ()) { UpdateLeasesBegin (); @@ -463,7 +465,7 @@ namespace data { LogPrint (eLogWarning, "LeaseSet2: Lease end date is from future ", lease.endDate); return 0; - } + } UpdateLease (lease, ts); } UpdateLeasesEnd (); @@ -502,7 +504,7 @@ namespace data return offset; } - void LeaseSet2::ReadFromBufferEncrypted (const uint8_t * buf, size_t len, + void LeaseSet2::ReadFromBufferEncrypted (const uint8_t * buf, size_t len, std::shared_ptr key, std::shared_ptr dest, const uint8_t * secret) { size_t offset = 0; @@ -758,7 +760,7 @@ namespace data memset (m_Buffer + offset, 0, signingKeyLen); offset += signingKeyLen; // num leases - auto numLeasesPos = offset; + auto numLeasesPos = offset; m_Buffer[offset] = num; offset++; // leases @@ -774,7 +776,7 @@ namespace data // already expired, skip skipped++; continue; - } + } if (ts > m_ExpirationTime) m_ExpirationTime = ts; // make sure leaseset is newer than previous, but adding some time to expiration date ts += (currentTime - tunnels[i]->GetCreationTime ()*1000LL)*2/i2p::tunnel::TUNNEL_EXPIRATION_TIMEOUT; // up to 2 secs @@ -792,7 +794,7 @@ namespace data num -= skipped; m_BufferLen -= skipped*LEASE_SIZE; m_Buffer[numLeasesPos] = num; - } + } // we don't sign it yet. must be signed later on } @@ -909,12 +911,12 @@ namespace data for (int i = 0; i < num; i++) { auto ts = tunnels[i]->GetCreationTime () + i2p::tunnel::TUNNEL_EXPIRATION_TIMEOUT - i2p::tunnel::TUNNEL_EXPIRATION_THRESHOLD; // in seconds, 1 minute before expiration - if (ts <= publishedTimestamp) - { + if (ts <= publishedTimestamp) + { // already expired, skip skipped++; - continue; - } + continue; + } if (ts > expirationTime) expirationTime = ts; memcpy (m_Buffer + offset, tunnels[i]->GetNextIdentHash (), 32); offset += 32; // gateway id @@ -930,7 +932,7 @@ namespace data num -= skipped; m_BufferLen -= skipped*LEASE2_SIZE; m_Buffer[numLeasesPos] = num; - } + } // update expiration if (expirationTime) {