add null check for netdb.NewIdentity and check offset > len to ensure nothing bad happens

This commit is contained in:
Lunar
2026-02-28 23:27:21 +10:00
parent bcfba9428e
commit 1dc2e579f4
+19 -17
View File
@@ -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<LocalDestination> 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<const BlindedPublicKey> key, std::shared_ptr<LocalDestination> 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)
{