Commit Graph
3 Commits
Author SHA1 Message Date
osobhandClaude Opus 5.5 90e050944f fix(format): refuse a local heap whose free list leaves the heap
libhdf5 walks a local heap's free list when it loads the heap's data and
refuses the heap ("bad heap free list") when a free block starts or ends
outside the data segment, or links to offset 0. We never looked at the
free list, so a damaged old-style group listed names read from the broken
heap: once the user block of cve-2021-36977.h5 was applied, its root
listed eight garbage names where libhdf5 fails.

LocalHeap::validate_free_list (new) mirrors H5HL__fl_deserialize, with a
cycle bound, and accepts H5HL_FREE_NULL (1) or an all-ones head as the
end of the list. Like libhdf5 it runs when the first name is needed, not
on parse, so an empty group with a damaged heap still lists as empty
(cve-2018-13871.h5, cve-2024-29166.h5, gh-4431-poc-03.h5 keep matching
h5py).

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-09-25 22:07:50 -05:00
Omar Sobh 297ee5ec17 security: Tier 4a — bounds-check audit + new dataset-read fuzz target
CI / test (push) Failing after 4s
- Add ensure_len(data, offset, needed) helper to chunked_read.rs,
  data_read.rs, and local_heap.rs (matching the existing btree_v1.rs/
  object_header.rs convention) and use it at every plain-arithmetic
  offset+size bounds check found in these files, closing usize-overflow
  panics reachable from crafted near-usize::MAX offsets/addresses.
- collect_chunk_info: add a depth-limited internal wrapper
  (collect_chunk_info_inner, MAX_CHUNK_BTREE_DEPTH=64) to reject a
  crafted self-referencing/cyclic B-tree v1 chunk index instead of
  recursing unboundedly (stack-overflow DoS).
- read_compound_fields: validate byte_offset+field_size against the
  compound's declared element size before slicing, instead of an
  unguarded out-of-bounds panic on a crafted member offset.
- read_chunked_data/_cached/_sweep/_indexed: guard `ndims - 1` against
  underflow for a degenerate zero-dimension chunked layout.
- copy_chunk_to_output: rewrite all offset/stride arithmetic (both the
  1-D fast path and the general N-D path) to use checked_add/checked_mul,
  skipping an out-of-range row/chunk instead of panicking on overflow.

Add a new cargo-fuzz target, fuzz_dataset_read, that walks every dataset
in a parsed file via the clawhdf5 facade and exercises the contiguous/
chunked/compact raw-data read paths that the existing fuzz_full_file
target doesn't reach. Seeded with the chunked/VDS/compound-relevant test
fixtures plus two crash regressions found during this pass (the
copy_chunk_to_output overflow and the ndims-1 underflow, both fixed
above — this target found real bugs within the first couple of runs).
Not wired into CI (nightly-only, multi-minute runs); documented in
fuzz/README.md as a manual/scheduled check instead. Also fixed the
README's stale rustyhdf5-format naming while touching this file.

Added regression tests for every fix (near-usize::MAX offsets, the
self-referencing B-tree case, the compound byte_offset overrun, the
zero-dim layout, and both copy_chunk_to_output overflow paths) so these
are caught by `cargo test`, not just the fuzz corpus.
2026-08-05 13:05:30 -07:00
redclawsystems 3f222f6956 Merge pull request 'docs(clawhdf5): document DType variants, fix unresolved doc links' (#17) from sdlc-docs/clawhdf5-types-20260514-165210 into main 2026-05-14 23:54:48 +00:00