You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@orc.apache.org by do...@apache.org on 2025/04/28 14:27:34 UTC

(orc) branch branch-1.9 updated: ORC-1879: [C++] Fix Heap Buffer Overflow in LZO Decompression

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

dongjoon pushed a commit to branch branch-1.9
in repository https://gitbox.apache.org/repos/asf/orc.git


The following commit(s) were added to refs/heads/branch-1.9 by this push:
     new 9a3a8d077 ORC-1879: [C++] Fix Heap Buffer Overflow in LZO Decompression
9a3a8d077 is described below

commit 9a3a8d077f04441732245daa927dcde0c8bfda41
Author: ffacs <ff...@gmail.com>
AuthorDate: Mon Apr 28 07:27:28 2025 -0700

    ORC-1879: [C++] Fix Heap Buffer Overflow in LZO Decompression
    
    ### What changes were proposed in this pull request?
    Fix Heap Buffer Overflow Vulnerability in LZO Decompression
    
    ### Why are the changes needed?
    This vulnerability has several security implications
    
    ### How was this patch tested?
    UT passed
    
    ### Was this patch authored or co-authored using generative AI tooling?
    NO
    
    Closes #2199 from ffacs/branch-1.9.
    
    Authored-by: ffacs <ff...@gmail.com>
    Signed-off-by: Dongjoon Hyun <do...@apache.org>
---
 c++/src/LzoDecompressor.cc    |  2 +-
 c++/test/TestDecompression.cc | 20 ++++++++++++++++++++
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/c++/src/LzoDecompressor.cc b/c++/src/LzoDecompressor.cc
index f494f4b65..68e25425c 100644
--- a/c++/src/LzoDecompressor.cc
+++ b/c++/src/LzoDecompressor.cc
@@ -342,7 +342,7 @@ namespace orc {
         char* literalOutputLimit = output + literalLength;
         if (literalOutputLimit > fastOutputLimit ||
             input + literalLength > inputLimit - SIZE_OF_LONG) {
-          if (literalOutputLimit > outputLimit) {
+          if (literalOutputLimit > outputLimit || input + literalLength > inputLimit) {
             throw MalformedInputException(input - inputAddress);
           }
 
diff --git a/c++/test/TestDecompression.cc b/c++/test/TestDecompression.cc
index c90801d72..a459d2aca 100644
--- a/c++/test/TestDecompression.cc
+++ b/c++/test/TestDecompression.cc
@@ -395,6 +395,26 @@ namespace orc {
     ASSERT_TRUE(!result->Next(&ptr, &length));
   }
 
+  TEST_F(TestDecompression, testLzoOverflow) {
+    const unsigned char bad_lzo_data[] = {// Header: compressedSize = 12, original = false
+                                          0x18, 0x00, 0x00,
+
+                                          // LZO body: token and literal length extension
+                                          0x00,  // token: extended literal length
+                                          0xFF,  // extension byte 1
+
+                                          // Literal data: only 10 bytes far less than 273
+                                          'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'};
+
+    std::unique_ptr<SeekableInputStream> result = createDecompressor(
+        CompressionKind_LZO,
+        std::make_unique<SeekableArrayInputStream>(bad_lzo_data, ARRAY_SIZE(bad_lzo_data)),
+        128 * 1024, *getDefaultPool(), getDefaultReaderMetrics());
+    const void* ptr;
+    int length;
+    EXPECT_THROW(result->Next(&ptr, &length), ParseError);
+  }
+
   TEST_F(TestDecompression, testLz4Empty) {
     const unsigned char buffer[] = {0};
     std::unique_ptr<SeekableInputStream> result = createDecompressor(