Skip to content

[Security] SIGSEGV (memory corruption/DoS) parsing untrusted parquet: cencoding.read_rle width overflow #985

Description

@plotarmordev

Security: SIGSEGV (memory corruption / DoS) parsing untrusted parquet — cencoding.read_rle width overflow

Affected: fastparquet (pip). Verified on 2026.5.0 (aarch64, Python 3.12, pristine wheel); likely earlier versions through the same Cython path. Not specific to platform per mechanism; verifier should reconfirm x86_64.

Summary: fastparquet/cencoding.pyx (compiled boundscheck=False, wraparound=False, cdivision=True) fails to bound the RLE width/length before decoding. For RLE / RLE_DICTIONARY encoded columns, bit_width is taken from the file-controlled schema element type_length and passed unvalidated into read_rle_bit_packed_hybridread_rle, which with a huge width, a short page blob, and a small output buffer reads/writes out of bounds and segfaults (SIGSEGV, exit 139). Reachable purely from a crafted .parquet file via fastparquet.ParquetFile(fn).to_pandas() — memory corruption + DoS on untrusted parquet ingest (ETL/gateway/validation boundaries).

Repro (3x each):

  1. Direct primitive:
import fastparquet.cencoding as ce
ce.read_rle(ce.NumpyIO(bytearray(bytes.fromhex("6ee9f7b8e80f1256b043"))), 31, 0x7fffffff, ce.NumpyIO(bytearray([0]*256)))
# -> process exits 139 (SIGSEGV)
  1. Crafted file (crafted-1668.parquet, 2210 B, RLE column type_length patched to 0x7fffffff, short page):
from fastparquet import ParquetFile
ParquetFile("crafted-1668.parquet").to_pandas()   # -> process exits 139 (SIGSEGV)
  1. Control: a normal parquet reads cleanly (ParquetFile(seed).to_pandas() returns rows) — not a false positive.

Impact: hard SIGSEGV (not a raised exception), out-of-bounds read/write class; DoS + memory-corruption potential on untrusted input.

Suggested fix: validate/clamp width (type_length, per-page bit_width, num_values) against buffer and output bounds before entering the C decode loop.

PoC file attached here (2210 B) or at the reporter's disposal; a private GHSA draft is also prepared and can be raised by a maintainer (or when I have write/admin rights).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions