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::resizewith no bound.orc::DataBuffer::resize mallocs that ~1.8e19-byte size, gets NULL, and memsets 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.