Skip to content

Commit 8bf2a7b

Browse files
committed
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.
1 parent 3ed403e commit 8bf2a7b

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

paligemma/image.cc

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,11 @@ const char* ParseUnsigned(const char* pos, const char* end, size_t& num) {
8585
}
8686
num = 0;
8787
for (; pos < end && std::isdigit(*pos); ++pos) {
88-
num *= 10;
89-
num += *pos - '0';
88+
const size_t digit = *pos - '0';
89+
if (num > (SIZE_MAX - digit) / 10) {
90+
return nullptr; // overflow
91+
}
92+
num = num * 10 + digit;
9093
}
9194
return pos;
9295
}
@@ -137,6 +140,14 @@ bool Image::ReadPPM(const hwy::Span<const char>& buf) {
137140
return false;
138141
}
139142
++pos;
143+
if (width == 0 || height == 0) {
144+
std::cerr << "Invalid zero dimension\n";
145+
return false;
146+
}
147+
if (width > SIZE_MAX / 3 || width * 3 > SIZE_MAX / height) {
148+
std::cerr << "Image dimensions overflow\n";
149+
return false;
150+
}
140151
const size_t data_size = width * height * 3;
141152
if (buf.cend() - pos < static_cast<ptrdiff_t>(data_size)) {
142153
std::cerr << "Insufficient data remaining\n";

util/basics.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,12 @@ struct Extents2D {
9191
constexpr Extents2D() : rows(0), cols(0) {}
9292
constexpr Extents2D(size_t rows, size_t cols) : rows(rows), cols(cols) {}
9393

94-
size_t Area() const { return rows * cols; }
94+
size_t Area() const {
95+
if (rows != 0 && cols > SIZE_MAX / rows) {
96+
HWY_ABORT("Tensor dimension overflow: rows=%zu cols=%zu", rows, cols);
97+
}
98+
return rows * cols;
99+
}
95100

96101
size_t rows;
97102
size_t cols;

0 commit comments

Comments
 (0)