Fix issue with handling of corrupted object header continuation messages (#5829)

An HDF5 file could be specifically constructed such that an object
header contained a corrupted continuation message which pointed
back to itself. This eventually resulted in an internal buffer being
allocated with too small of a size, leading to a heap buffer overflow
when encoding an object header message into it. This has been fixed
by checking the expected number of deserialized object header chunks
against the actual value as chunks are being deserialized.

Fixes CVE-2025-6816, CVE-2025-6856, CVE-2025-2923
This commit is contained in:
jhendersonHDF
2025-09-26 13:13:10 -05:00
committed by GitHub
parent 877cbf79a7
commit 29c847a43d
2 changed files with 17 additions and 6 deletions
+6
View File
@@ -502,6 +502,12 @@ Added Fortran wrapper h5fdsubfiling_get_file_mapping_f() for the subfiling file
## Library
### Fixed security issues CVE-2025-6816, CVE-2025-6856 and CVE-2025-2923
A specially constructed HDF5 file could contain a corrupted object header with a continuation message that points back to itself. This could result in an internal buffer being allocated with too small of a size, leading to a heap buffer overflow. This has been fixed by checking the expected number of object header chunks against the actual value as chunks are being deserialized.
Fixes GitHub issues #5571, #5574 and #5381
### Fixed security issue CVE-2025-6750
A heap buffer overflow occurred because an mtime message was not properly decoded, resulting in a buffer of size 0 being passed into the encoder. This has been fixed by decoding old and new mtime messages which will allow invalid message size to be detected.
+11 -6
View File
@@ -1040,10 +1040,9 @@ H5O_protect(const H5O_loc_t *loc, unsigned prot_flags, bool pin_all_chunks)
*/
curr_msg = 0;
while (curr_msg < cont_msg_info.nmsgs) {
H5O_chunk_proxy_t *chk_proxy; /* Proxy for chunk, to bring it into memory */
#ifndef NDEBUG
size_t chkcnt = oh->nchunks; /* Count of chunks (for sanity checking) */
#endif /* NDEBUG */
H5O_chunk_proxy_t *chk_proxy; /* Proxy for chunk, to bring it into memory */
unsigned chunkno; /* Chunk number for chunk proxy */
size_t chkcnt = oh->nchunks; /* Count of chunks (for sanity checking) */
/* Bring the chunk into the cache */
/* (which adds to the object header) */
@@ -1056,14 +1055,20 @@ H5O_protect(const H5O_loc_t *loc, unsigned prot_flags, bool pin_all_chunks)
/* Sanity check */
assert(chk_proxy->oh == oh);
assert(chk_proxy->chunkno == chkcnt);
assert(oh->nchunks == (chkcnt + 1));
chunkno = chk_proxy->chunkno;
/* Release the chunk from the cache */
if (H5AC_unprotect(loc->file, H5AC_OHDR_CHK, cont_msg_info.msgs[curr_msg].addr, chk_proxy,
H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, NULL, "unable to release object header chunk");
if (chunkno != chkcnt)
HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "incorrect chunk number for object header chunk");
if (oh->nchunks != (chkcnt + 1))
HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL,
"incorrect number of chunks after deserializing object header chunk");
/* Advance to next continuation message */
curr_msg++;
} /* end while */