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:
@@ -80,6 +80,9 @@ pub enum FormatError {
|
||||
InvalidLocalHeapSignature,
|
||||
/// Invalid local heap version.
|
||||
InvalidLocalHeapVersion(u8),
|
||||
/// A local heap's free list points outside its data segment (libhdf5:
|
||||
/// "bad heap free list").
|
||||
InvalidLocalHeapFreeList,
|
||||
/// Invalid B-tree v1 signature.
|
||||
InvalidBTreeSignature,
|
||||
/// Invalid B-tree node type.
|
||||
@@ -278,6 +281,9 @@ impl fmt::Display for FormatError {
|
||||
FormatError::InvalidLocalHeapSignature => {
|
||||
write!(f, "invalid local heap signature")
|
||||
}
|
||||
FormatError::InvalidLocalHeapFreeList => {
|
||||
write!(f, "bad local heap free list")
|
||||
}
|
||||
FormatError::InvalidLocalHeapVersion(v) => {
|
||||
write!(f, "invalid local heap version: {v}")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user