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 ownPOWER_OF_TWOcheck) - 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.