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 <[email protected]>
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 <[email protected]>
    Signed-off-by: Dongjoon Hyun <[email protected]>
---
 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(

Reply via email to