Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions release_docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ The `h5repack` tool now obtains its default low and high library version bounds

## Library

### Fixed a heap buffer overflow when decoding a shared message list

When reading a shared object header message (SOHM) list from the metadata cache, `H5SM__cache_list_deserialize()` allocated the message array for `list_max` entries but drove the decode loop with the `num_messages` count read from the on-disk index header. A corrupted or malicious file whose `num_messages` exceeds `list_max` caused writes past the end of the array and reads past the end of the input buffer. The count is now validated against `list_max` before the loop runs.

### HTTP 403 errors in the ROS3 VFD for object keys with special characters

The ROS3 VFD did not URI-encode the S3 object key when building the HTTP request path, so keys containing characters that AWS Signature Version 4 requires to be percent-encoded — such as the '=' in Hive-style `key=value` partition prefixes, '+', or spaces — produced a signed request whose signature did not match S3's server-side recomputation. S3 rejects such requests with `SignatureDoesNotMatch`, which surfaces as an HTTP 403 error (indistinguishable from a permissions error on a HEAD request), even though tools like the AWS CLI could access the same object. The object key is now percent-encoded exactly once when the request path is built, matching the behavior of other S3 clients. Note that URLs must now be passed to the ROS3 VFD with their object keys unencoded; a key that was pre-encoded as a workaround for this issue will now be double-encoded and fail to resolve.
Expand Down
14 changes: 14 additions & 0 deletions src/H5SMcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,12 @@ H5SM__cache_list_verify_chksum(const void *_image, size_t H5_ATTR_UNUSED len, vo
assert(image);
assert(udata);

/* The buffer only holds list_max messages; a corrupted header whose message
* count exceeds that would size the checksum region past the end of it.
*/
if (udata->header->num_messages > udata->header->list_max)
HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, FAIL, "number of SOHM messages exceeds list size");

/* Exact size with checksum at the end */
chk_size = H5SM_LIST_SIZE(udata->f, udata->header->num_messages);

Expand Down Expand Up @@ -552,6 +558,14 @@ H5SM__cache_list_deserialize(const void *_image, size_t H5_ATTR_NDEBUG_UNUSED le
HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, NULL, "bad SOHM list signature");
image += H5_SIZEOF_MAGIC;

/* The message array is sized for list_max entries; a list index always
* holds at most that many before it is promoted to a B-tree. Reject a
* corrupted header whose message count would drive the decode loop past
* the allocation and the input buffer.
*/
if (udata->header->num_messages > udata->header->list_max)
HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, NULL, "number of SOHM messages exceeds list size");

/* Read messages into the list array */
ctx.sizeof_addr = H5F_SIZEOF_ADDR(udata->f);
for (u = 0; u < udata->header->num_messages; u++) {
Expand Down
Loading