From a600573200e632258b444aa41a773deea007d4c1 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Mon, 19 Jan 2026 15:39:43 +0100 Subject: [PATCH] GH-48900: [C++] Avoid memory blowup with excessive variadic buffer count in IPC --- cpp/src/arrow/ipc/reader.cc | 18 ++++++++++++------ testing | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/cpp/src/arrow/ipc/reader.cc b/cpp/src/arrow/ipc/reader.cc index 6a20dbb8c85..8e125fc5ede 100644 --- a/cpp/src/arrow/ipc/reader.cc +++ b/cpp/src/arrow/ipc/reader.cc @@ -250,18 +250,24 @@ class ArrayLoader { } } - Result GetVariadicCount(int i) { + Result GetVariadicCount(int i) { auto* variadic_counts = metadata_->variadicBufferCounts(); CHECK_FLATBUFFERS_NOT_NULL(variadic_counts, "RecordBatch.variadicBufferCounts"); if (i >= static_cast(variadic_counts->size())) { return Status::IOError("variadic_count_index out of range."); } int64_t count = variadic_counts->Get(i); - if (count < 0 || count > std::numeric_limits::max()) { - return Status::IOError( - "variadic_count must be representable as a positive int32_t, got ", count, "."); + if (count < 0) { + return Status::IOError("variadic buffer count must be positive"); + } + // Detect an excessive variadic buffer count to avoid potential memory blowup + // (GH-48900). + const auto max_buffer_count = + static_cast(metadata_->buffers()->size()) - buffer_index_; + if (count > max_buffer_count) { + return Status::IOError("variadic buffer count exceeds available number of buffers"); } - return static_cast(count); + return count; } Status GetFieldMetadata(int field_index, ArrayData* out) { @@ -398,7 +404,7 @@ class ArrayLoader { ARROW_ASSIGN_OR_RAISE(auto data_buffer_count, GetVariadicCount(variadic_count_index_++)); out_->buffers.resize(data_buffer_count + 2); - for (size_t i = 0; i < data_buffer_count; ++i) { + for (int64_t i = 0; i < data_buffer_count; ++i) { RETURN_NOT_OK(GetBuffer(buffer_index_++, &out_->buffers[i + 2])); } return Status::OK(); diff --git a/testing b/testing index 19dda67f485..7b641152dcb 160000 --- a/testing +++ b/testing @@ -1 +1 @@ -Subproject commit 19dda67f485ffb3ffa92f4c6fa083576ef052d58 +Subproject commit 7b641152dcb0f9e197ebe24a1986151849250959