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]>
This commit is contained in:
@@ -273,6 +273,13 @@
|
||||
- CI keeps zlib-ng building and tested; the arm64 job no longer needs cmake.
|
||||
|
||||
### Correctness
|
||||
- `clawhdf5-format` reader: an old-style group whose local heap has a free
|
||||
list pointing outside the heap was listed with names read from the broken
|
||||
heap (garbage names on `cve-2021-36977.h5` once its user block was
|
||||
applied). libhdf5 refuses such a heap ("bad heap free list"); so do we now,
|
||||
with `FormatError::InvalidLocalHeapFreeList`. As in libhdf5 the free list
|
||||
is checked when the first name is read (`LocalHeap::validate_free_list`,
|
||||
new), so an empty group with a damaged heap still lists as empty.
|
||||
- **Files with a user block** (`h5py.File(..., userblock_size=N)`, `h5jam`;
|
||||
the superblock at 512, 1024, …) could not be read: every address in the
|
||||
file is relative to the superblock, but it was applied from byte 0
|
||||
|
||||
Reference in New Issue
Block a user