Fix integer overflow in tensor dimensions and PPM parser

- util/basics.h: Add overflow check in Extents2D::Area() before
  computing rows*cols. Malicious model files with large dimension
  values could cause a silent size_t overflow, leading to undersized
  allocations and subsequent heap buffer overflows.

- paligemma/image.cc: Add overflow check for width*height*3 in
  ReadPPM(). A crafted PPM file with large dimensions could overflow
  the data_size computation, resulting in an undersized buffer and
  out-of-bounds writes.

- paligemma/image.cc: Add overflow detection in ParseUnsigned() to
  reject values that would overflow size_t during decimal parsing.
This commit is contained in:
Sharad Boni 2026-04-15 15:50:46 -07:00
parent 221d8df516
commit e260706346
2 changed files with 19 additions and 3 deletions

View File

@ -83,8 +83,11 @@ const char* ParseUnsigned(const char* pos, const char* end, size_t& num) {
}
num = 0;
for (; pos < end && std::isdigit(*pos); ++pos) {
num *= 10;
num += *pos - '0';
const size_t digit = *pos - '0';
if (num > (SIZE_MAX - digit) / 10) {
return nullptr; // overflow
}
num = num * 10 + digit;
}
return pos;
}
@ -136,6 +139,14 @@ bool Image::ReadPPM(const hwy::Span<const char>& buf) {
return false;
}
++pos;
if (width == 0 || height == 0) {
std::cerr << "Invalid zero dimension\n";
return false;
}
if (width > SIZE_MAX / 3 || width * 3 > SIZE_MAX / height) {
std::cerr << "Image dimensions overflow\n";
return false;
}
const size_t data_size = width * height * 3;
if (buf.cend() - pos < static_cast<ptrdiff_t>(data_size)) {
std::cerr << "Insufficient data remaining\n";

View File

@ -97,7 +97,12 @@ struct Extents2D {
constexpr Extents2D() : rows(0), cols(0) {}
constexpr Extents2D(size_t rows, size_t cols) : rows(rows), cols(cols) {}
size_t Area() const { return rows * cols; }
size_t Area() const {
if (rows != 0 && cols > SIZE_MAX / rows) {
HWY_ABORT("Tensor dimension overflow: rows=%zu cols=%zu", rows, cols);
}
return rows * cols;
}
size_t rows;
size_t cols;