fix(format): validate chunk dimensions and chunk index offsets like libhdf5
A chunk dimension of 0 read a dataset as all fill values, 0x80000000 made
an 8 GiB chunk, and a chunk dimension the chunk index's offsets are not
multiples of read chunks at the wrong place (cve-2018-11205). libhdf5
refuses all of these; now so does clawhdf5:
- DataLayout::parse (H5O__layout_decode): no chunk dimension 0 ("bad chunk
dimension value"), at most 33 dimensions, and before layout v4 at least
2 ("bad dimensions for chunked storage"). New
FormatError::InvalidChunkDimensions.
- Reading a chunked dataset (H5D__chunk_init / H5D__chunk_set_sizes): the
chunk rank must match the dataspace's and a chunk must be under 4 GiB.
One chunked_read::chunk_geometry replaces the four copies of the rank
check.
- v1 B-tree chunk index (H5D__btree_decode_key): every key's offsets must
be multiples of the chunk dimensions, including the keys that only bound
a node, which is where cve-2018-11205's bad dimension shows. New
chunked_read::collect_chunk_info_checked; the chunked read and selection
paths use it.
New interop test header_validation_interop.rs: h5py writes chunked files
(layout v3 and v4), the script corrupts the chunk dimension, and
clawhdf5 must read exactly the copies h5py reads.
Conformance (cached corpus, tank): 570 ok, unchanged; cve-2018-11205 now
refuses the dataset h5py refuses; six more objects that already failed now
fail with libhdf5's reason.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
@@ -210,6 +210,10 @@ pub enum FormatError {
|
||||
/// libhdf5's own error text): size 0, bit fields outside the type,
|
||||
/// an empty enum name, a compound member outside its compound, …
|
||||
InvalidDatatype(String),
|
||||
/// A chunked layout whose chunk dimensions libhdf5 refuses: a zero
|
||||
/// dimension, a rank that does not match the dataspace, or a chunk of
|
||||
/// 4 GiB or more.
|
||||
InvalidChunkDimensions(String),
|
||||
}
|
||||
|
||||
impl fmt::Display for FormatError {
|
||||
@@ -460,6 +464,9 @@ impl fmt::Display for FormatError {
|
||||
FormatError::InvalidDatatype(why) => {
|
||||
write!(f, "invalid datatype: {why}")
|
||||
}
|
||||
FormatError::InvalidChunkDimensions(why) => {
|
||||
write!(f, "invalid chunk dimensions: {why}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user