HDF5 onion VFD revision-record integer-overflow PoC (illustrative fields)
Proof-of-concept material for a huntr Model Format Vulnerability report
against HDFGroup/hdf5 (src/H5FDonion_index.c,
H5FD__onion_revision_record_decode()).
evil_revision_record.bin is a 64-byte buffer matching the exact,
byte-for-byte field layout of an onion-VFD revision record header, verified
directly against the live source (H5FDonion_index.c, function starting at
line 586; signature/version constants from H5FDonion_index.h):
- bytes 0-3: signature
"ORRS" (H5FD_ONION_REVISION_RECORD_SIGNATURE)
- byte 4: version
1 (H5FD_ONION_REVISION_RECORD_VERSION_CURR)
- bytes 5-7: reserved/skipped (decode starts reading fixed fields at
buf+8)
- bytes 8-15:
revision_num (uint64) = 0
- bytes 16-23:
parent_revision_num (uint64) = 0xFFFFFFFFFFFFFFFF (sentinel)
- bytes 24-39:
time_of_creation (16 bytes) = 0
- bytes 40-47:
logical_eof (uint64) = 0
- bytes 48-51:
page_size (uint32) = 4096 (must be non-zero power of two -
this passes the function's own POWER_OF_TWO check)
- bytes 52-59:
n_entries (uint64) = 0xFFFFFFFFFFFFFFFF - the
attacker-controlled field this report is about
- bytes 60-63:
comment_size (uint32) = 0
H5FD__onion_ingest_revision_record() (lines 145, 149-150) allocates
H5MM_calloc(n_entries * sizeof(entry)) from this field with no upper-bound
check. H5MM_calloc is literally #define H5MM_calloc(Z) calloc(1, Z) -
the multiplication n_entries * sizeof(entry) happens in the caller, in
64-bit arithmetic, BEFORE calloc's own internal overflow protection ever
sees it. With n_entries = 0xFFFFFFFFFFFFFFFF and
H5FD_ONION_ENCODED_SIZE_INDEX_ENTRY = 20 (bytes per entry,
H5FDonion_index.h), the true product wraps around 2^64, which can produce
an undersized calloc allocation followed by a decode loop that writes
n_entries index entries into it - a potential heap buffer overflow, not
just a disproportionate-allocation DoS.
Reachable via H5Pset_fapl_onion(), a documented public API (no
experimental/unsupported marking) built into the base HDF5 library
(CMakeLists.txt, no feature flag needed). The project's own SECURITY.md
explicitly lists DoS/crash as "Usually In Scope".
Honest limits (not swept under the rug)
This 64-byte buffer is the isolated, byte-verified revision-record header
fragment - it is not a complete onion-format overlay file spliced onto
a real HDF5 base file, and no live crash/heap-overflow was reproduced on
this host (building libhdf5 with the onion VFD from source, or installing
the system package, was not done here - no root access to install system
packages, and a from-source build was judged too large an addition for this
report). An earlier independent blind-adversarial code review reached the
same conclusion from reading the same source and explicitly flagged this
exact escalation (integer-overflow -> undersized calloc -> OOB write) as
"plausible, but not proven all the way to a live crash" - this report
does not claim more certainty than that review established.
Impact: potentially a heap buffer overflow (not just DoS) via a crafted
onion-format revision record with an oversized n_entries field, though the
escalation from integer-overflow to actual out-of-bounds write has not been
runtime-confirmed.