Skip to content

Commit 45e4584

Browse files
committed
GH-48900: [C++] Avoid memory blowup with excessive variadic buffer count in IPC
1 parent 34045db commit 45e4584

File tree

2 files changed

+13
-7
lines changed

2 files changed

+13
-7
lines changed

cpp/src/arrow/ipc/reader.cc

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -250,18 +250,24 @@ class ArrayLoader {
250250
}
251251
}
252252

253-
Result<size_t> GetVariadicCount(int i) {
253+
Result<int64_t> GetVariadicCount(int i) {
254254
auto* variadic_counts = metadata_->variadicBufferCounts();
255255
CHECK_FLATBUFFERS_NOT_NULL(variadic_counts, "RecordBatch.variadicBufferCounts");
256256
if (i >= static_cast<int>(variadic_counts->size())) {
257257
return Status::IOError("variadic_count_index out of range.");
258258
}
259259
int64_t count = variadic_counts->Get(i);
260-
if (count < 0 || count > std::numeric_limits<int32_t>::max()) {
261-
return Status::IOError(
262-
"variadic_count must be representable as a positive int32_t, got ", count, ".");
260+
if (count < 0) {
261+
return Status::IOError("variadic buffer count must be positive");
262+
}
263+
// Detect an excessive variadic buffer count to avoid potential memory blowup
264+
// (GH-48900).
265+
const auto max_buffer_count =
266+
static_cast<int64_t>(metadata_->buffers()->size()) - buffer_index_;
267+
if (count > max_buffer_count) {
268+
return Status::IOError("variadic buffer count exceeds available number of buffers");
263269
}
264-
return static_cast<size_t>(count);
270+
return count;
265271
}
266272

267273
Status GetFieldMetadata(int field_index, ArrayData* out) {
@@ -398,7 +404,7 @@ class ArrayLoader {
398404
ARROW_ASSIGN_OR_RAISE(auto data_buffer_count,
399405
GetVariadicCount(variadic_count_index_++));
400406
out_->buffers.resize(data_buffer_count + 2);
401-
for (size_t i = 0; i < data_buffer_count; ++i) {
407+
for (int64_t i = 0; i < data_buffer_count; ++i) {
402408
RETURN_NOT_OK(GetBuffer(buffer_index_++, &out_->buffers[i + 2]));
403409
}
404410
return Status::OK();

0 commit comments

Comments
 (0)