Skip to content

Commit

Permalink
Fixes and additions of some of the bounds checks in
Browse files Browse the repository at this point in the history
SystemPacketBuffer::New().

With the data length types changed to size_t, the bounds checks for the lengths
need to be appropriately modified so that we ensure that overflow does
not happen and the buffer allocation is performed correctly as requested
by the caller of the API.
  • Loading branch information
pidarped committed May 13, 2024
1 parent 3600a50 commit 8256050
Showing 1 changed file with 34 additions and 13 deletions.
47 changes: 34 additions & 13 deletions src/system/SystemPacketBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -508,32 +508,53 @@ void PacketBuffer::AddRef()

PacketBufferHandle PacketBufferHandle::New(size_t aAvailableSize, uint16_t aReservedSize)
{
// Adding three 16-bit-int sized numbers together will never overflow
// assuming int is at least 32 bits.
// Ensure that SIZE_MAX is at least 32 bits
static_assert(INT_MAX >= INT32_MAX, "int is not big enough");
static_assert(SIZE_MAX >= INT_MAX, "Our additions may not fit in size_t");

// Sanity check for kStructureSize and putting an upper bound.
static_assert(PacketBuffer::kStructureSize == sizeof(PacketBuffer), "PacketBuffer size mismatch");
static_assert(PacketBuffer::kStructureSize < UINT16_MAX, "Check for overflow more carefully");
static_assert(SIZE_MAX >= INT_MAX, "Our additions might not fit in size_t");
static_assert(PacketBuffer::kMaxSizeWithoutReserve <= UINT32_MAX, "PacketBuffer may have size not fitting uint32_t");
static_assert(PacketBuffer::kStructureSize < UINT16_MAX, "kStructureSize should not exceed UINT16_MAX");
static_assert(PacketBuffer::kMaxSizeWithoutReserve <= UINT16_MAX, "PacketBuffer may have size not fitting uint16_t");

// Have a bounds check for aAvailableSize to ensure that
// the next overflow check is done correctly.
if (aAvailableSize > UINT32_MAX)
{
ChipLogError(chipSystemLayer, "PacketBuffer: AvailableSize of a buffer cannot exceed UINT32_MAX");
return PacketBufferHandle();
}

// Cast all to uint64_t and add to consider the widest possible result.
uint64_t sumOfSizes = static_cast<uint64_t>(aAvailableSize) + static_cast<uint64_t>(aReservedSize) +
static_cast<uint64_t>(PacketBuffer::kStructureSize);
uint64_t sumOfAvailAndReserved = static_cast<uint64_t>(aAvailableSize) + static_cast<uint64_t>(aReservedSize);

// Ensure that the sum does not overflow a size_t whose max value is at
// least INT_MAX.
if (sumOfSizes > std::numeric_limits<size_t>::max())
{
ChipLogError(chipSystemLayer, "PacketBuffer: Sizes of allocation request are invalid");
return PacketBufferHandle();
}

#if CHIP_SYSTEM_CONFIG_USE_LWIP
// LwIP based APIs have a maximum buffer size of UINT16_MAX. Ensure that
// limit is met during allocation.
VerifyOrDieWithMsg(aAvailableSize + aReservedSize < UINT16_MAX, chipSystemLayer,
"LwIP based systems can handle only up to UINT16_MAX!");
VerifyOrDieWithMsg(sumOfAvailAndReserved < UINT16_MAX, chipSystemLayer, "LwIP based systems can handle only up to UINT16_MAX!");
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

// When `aAvailableSize` fits in uint16_t (as tested below) and size_t is at least 32 bits (as asserted above),
// these additions will not overflow.
const size_t lAllocSize = aReservedSize + aAvailableSize;
// The above check against the size_t limit ensures that the below sum will not
// overflow.
const size_t lAllocSize = static_cast<size_t>(sumOfAvailAndReserved);
const size_t lBlockSize = PacketBuffer::kStructureSize + lAllocSize;
PacketBuffer * lPacket;

CHIP_SYSTEM_FAULT_INJECT(FaultInjection::kFault_PacketBufferNew, return PacketBufferHandle());

// TODO: Change the max to a lower value
if (aAvailableSize > UINT32_MAX || lAllocSize > PacketBuffer::kMaxSizeWithoutReserve || lBlockSize > UINT32_MAX)
if (lAllocSize > PacketBuffer::kMaxSizeWithoutReserve)
{
ChipLogError(chipSystemLayer, "PacketBuffer: allocation too large.");
ChipLogError(chipSystemLayer, "PacketBuffer: allocation exceeding buffer capacity limits.");
return PacketBufferHandle();
}

Expand Down

0 comments on commit 8256050

Please sign in to comment.