This is an automated email from the ASF dual-hosted git repository.

apitrou pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/main by this push:
     new 421a475fc5 GH-48900: [C++] Avoid memory blowup with excessive variadic 
buffer count in IPC (#48901)
421a475fc5 is described below

commit 421a475fc592041a62bcb1eb906cf0a65e37f1f1
Author: Antoine Pitrou <[email protected]>
AuthorDate: Wed Jan 21 10:16:51 2026 +0100

    GH-48900: [C++] Avoid memory blowup with excessive variadic buffer count in 
IPC (#48901)
    
    ### Rationale for this change
    
    An incorrect variadic buffer count could easily blow up memory when 
reserving a vector of Buffers, even though the RecordBatch has a lot less 
buffers available.
    
    Reported by OSS-Fuzz at https://issues.oss-fuzz.com/issues/476180608, and 
separately by Silas Boch.
    
    ### What changes are included in this PR?
    
    Pre-validate the variadic buffer count read from the IPC RecordBatch table. 
Initial patch by Silas Boch.
    
    ### Are these changes tested?
    
    Yes, by additional fuzz regression file.
    
    ### Are there any user-facing changes?
    
    No.
    
    **This PR contains a "Critical Fix".** (If the changes fix either (a) a 
security vulnerability, (b) a bug that caused incorrect or invalid data to be 
produced, or (c) a bug that causes a crash (even when the API contract is 
upheld), please provide explanation. If not, you can remove this.)
    
    * GitHub Issue: #48900
    
    Authored-by: Antoine Pitrou <[email protected]>
    Signed-off-by: Antoine Pitrou <[email protected]>
---
 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 6a20dbb8c8..8e125fc5ed 100644
--- a/cpp/src/arrow/ipc/reader.cc
+++ b/cpp/src/arrow/ipc/reader.cc
@@ -250,18 +250,24 @@ class ArrayLoader {
     }
   }
 
-  Result<size_t> GetVariadicCount(int i) {
+  Result<int64_t> GetVariadicCount(int i) {
     auto* variadic_counts = metadata_->variadicBufferCounts();
     CHECK_FLATBUFFERS_NOT_NULL(variadic_counts, 
"RecordBatch.variadicBufferCounts");
     if (i >= static_cast<int>(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<int32_t>::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<int64_t>(metadata_->buffers()->size()) - buffer_index_;
+    if (count > max_buffer_count) {
+      return Status::IOError("variadic buffer count exceeds available number 
of buffers");
     }
-    return static_cast<size_t>(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 19dda67f48..7b641152dc 160000
--- a/testing
+++ b/testing
@@ -1 +1 @@
-Subproject commit 19dda67f485ffb3ffa92f4c6fa083576ef052d58
+Subproject commit 7b641152dcb0f9e197ebe24a1986151849250959

Reply via email to