0xzap's picture
Upload folder using huggingface_hub
7dc1a1e verified
|
Raw
History Blame Contribute Delete
1.72 kB
# orc-encoding-kind-nullwrite-poc
PoC `.orc` for a native crash in Apache Arrow's ORC C++ reader (pyarrow 25.0.0, latest), hit by `pyarrow.orc.read_table` on the file β€” one corrupted byte in the stripe footer.
the byte is a `ColumnEncoding.kind` inside the stripe footer (`StripeFooter.columns[i].kind`, protobuf field 1). set it to an out-of-range enum value (`27` instead of `2` = `DIRECT_V2`) and the column reader picks the wrong RLE/decode path, computes an underflowed element count (~`0xffff…`, i.e. a huge uint64), and passes it straight to `orc::ColumnVectorBatch::resize` with no bound. `orc::DataBuffer<char>::resize` `malloc`s that ~1.8e19-byte size, gets `NULL`, and `memset`s into the NULL dest β†’ write to address 0 β†’ SIGSEGV. not a clean `ArrowInvalid`, not a `bad_alloc` that unwinds β€” a hard native crash.
## files
- `orc_min.orc` β€” the crafted file (13251 bytes). `pyarrow.orc.read_table("orc_min.orc")` β†’ SIGSEGV.
- `orc_encoding_kind_poc.py` β€” deterministic generator: builds a rich 14-column table, finds a `DIRECT_V2` encoding in the stripe footer, flips the `kind` byte to 27, verifies the crash in a fresh subprocess.
- `read_orc.py` β€” the plain read path (`orc.read_table(argv[1])`), run per-file in its own process.
## repro
pip install pyarrow==25.0.0
python orc_encoding_kind_poc.py # -> flips kind at offset 11938, writes orc_min.orc, rc=-11
python read_orc.py orc_min.orc ; echo $? # -> 139 (128 + SIGSEGV)
it's a reliable NULL-pointer write / DoS on load of an untrusted `.orc`, not a controllable OOB write (the underflowed size is too big to allocate β†’ malloc NULL β†’ fault at 0). no RCE claimed. single byte, no compression, ordinary columns.