You need to agree to share your contact information to access this model

This repository is publicly accessible, but you have to accept the conditions to access its files and content.

Log in or Sign Up to review the conditions and access this model content.

YAML Metadata Warning:empty or missing yaml metadata in repo card

Check out the documentation for more information.

Apache ORC C++ dictionary-length cumulative-overflow PoC

Tested against Apache ORC commit:

af4cbf36b051c176f0d13ae5a7ac436ada8aeccf

Summary

The C++ string-dictionary loader validates each decoded dictionary entry length for negativity, but it adds the individually valid values into signed int64_t prefix sums without checking overflow.

The 251-byte trigger contains three non-negative dictionary lengths:

INT64_MAX, INT64_MAX, 2

Their mathematical sum is 2^64. The prefix sums overflow signed int64_t, the final dictionary blob size wraps to zero, and the row reader returns a StringVectorBatch whose first row advertises length INT64_MAX over a one-byte backing allocation. A consumer that reads the returned string data causes a heap-buffer-overflow.

The valid 228-byte control contains the strings a, bb, a, bb and exits normally.

Reproduce

Build prerequisites are the same as Apache ORC C++. Then run:

ORC_SRC=/path/to/orc ./reproduce.sh

The script configures current ORC with AddressSanitizer and UndefinedBehaviorSanitizer, builds the standalone reader harness, and runs both fixtures.

Expected control:

row=0 length=1
checksum=97
value=a
row=1 length=2
checksum=0
value=bb
...
rows=4

Expected trigger:

row=0 length=9223372036854775807
DictionaryLoader.cc:79:22: runtime error: signed integer overflow
ColumnReader.cc:591:57: runtime error: signed integer overflow
ERROR: AddressSanitizer: heap-buffer-overflow
READ of size 1
0x... is located 0 bytes after 1-byte region

The harness limits downstream inspection to 1 MiB. It does not attempt to materialize the advertised INT64_MAX bytes.

Fixtures

88477314865f2fdf594489fdd08a9996447a549245be27cddc303444d2cf5068  control-two-entry-dictionary.orc
0f3625588531b294bfebb5c9f19b3099dbc62815ce31487cf8c102f0de4f1034  trigger-wrapped-zero-offsets.orc

The generator embeds the Apache ORC 2.2.2 control and changes only:

  • the dictionary LENGTH stream;
  • that stream's serialized byte length;
  • the stripe data length; and
  • the dictionary entry count.

Root cause

At c++/src/DictionaryLoader.cc:73-80, each raw entry passes the existing negative-value check before the unchecked signed addition:

if (lengthArray[i] < 0) {
  throw ParseError(...);
}
lengthArray[i] += lengthArray[i - 1];

At c++/src/ColumnReader.cc:588-593, the corrupted offsets are subtracted again and exposed through StringVectorBatch::length and StringVectorBatch::data.

Prior-art distinction

ORC-312 / PR #224 fixed the case where one decoded dictionary length was already negative before accumulation. This trigger uses three individually non-negative lengths and overflows only during the prefix-sum addition after that check.

ORC-2192 / PR #2673 covers direct-encoded strings, not dictionary prefix sums.

Suggested fix

Before adding each entry, reject:

lengthArray[i] >
    std::numeric_limits<int64_t>::max() - lengthArray[i - 1]

Also validate that every cumulative offset is monotonic, fits the backing dictionary blob, and can be safely subtracted before exposing string lengths.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support