Skip to content

Integer overflow in tensor byte-size calculation in memory_helpers.cc #3552

@Forbiddem

Description

@Forbiddem

Summary

tensorflow/lite/micro/memory_helpers.cc computes the byte length of tensors using a 32-bit signed int running product before assigning the result to a size_t. Because tensor shape dimensions and element type sizes come from the (untrusted) flatbuffer model, a model with a shape such as [65536, 65536] over a 4-byte element type produces an element-count product of 2^32, which wraps to 0 in the existing code and causes *bytes = 0.

The same pattern appears in three places:

  • BytesRequiredForTensor (called during initial allocation from the flatbuffer model)
  • TfLiteEvalTensorByteLength
  • AllocateOutputDimensionsFromInput

A downstream allocator that trusts *bytes then operates on a tensor whose advertised size is 0 while its dimensions imply ~17 GiB of storage, which is a memory corruption surface when models are loaded from an untrusted source.

Reproducer

The arithmetic from BytesRequiredForTensor extracted into a self-contained C++ program:

size_t VulnerableBytesRequiredForTensor(const int32_t* shape, size_t rank,
                                        size_t type_size) {
  int element_count = 1;
  for (size_t n = 0; n < rank; ++n) {
    element_count *= shape[n];
  }
  return element_count * type_size;
}

int main() {
  const int32_t shape[] = {65536, 65536};
  const size_t type_size = 4;  // float32
  // Mathematically: 17,179,869,184 bytes.
  // Observed:       0 (signed 32-bit wraparound).
  std::cout << VulnerableBytesRequiredForTensor(shape, 2, type_size) << "\n";
}

Proposed fix

See PR — running product moved to size_t, every multiplication guarded against size_t overflow, negative dimensions rejected, and three regression tests added in memory_helpers_test.cc.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions