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/17 00:55:31 UTC

(orc) branch branch-2.0 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-2.0
in repository https://gitbox.apache.org/repos/asf/orc.git


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

commit 807dcac3d8d197f9006714fd6ebf091c1b00d662
Author: ffacs <ff...@gmail.com>
AuthorDate: Thu Apr 17 09:54:46 2025 +0900

    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 #2191 from ffacs/main.
    
    Authored-by: ffacs <ff...@gmail.com>
    Signed-off-by: Dongjoon Hyun <do...@apache.org>
    (cherry picked from commit 6b78a0dde976c6b978f1ba7c9c4b0aba291a2058)
    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 e729fc8d8..12e0ffe9f 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(