This is an automated email from the ASF dual-hosted git repository.
dongjoon pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/orc.git
The following commit(s) were added to refs/heads/main by this push:
new 6b78a0dde ORC-1879: [C++] Fix Heap Buffer Overflow in LZO Decompression
6b78a0dde is described below
commit 6b78a0dde976c6b978f1ba7c9c4b0aba291a2058
Author: ffacs <[email protected]>
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 <[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 dc9709403..125c5e85a 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(