From a0635c9ad7c8948326344ba1a1f35aa97e398f55c59d47f6222f4da4b8e6011e Mon Sep 17 00:00:00 2001 From: Atri Bhattacharya Date: Mon, 24 Oct 2022 06:53:22 +0000 Subject: [PATCH 1/2] Accepting request 1030627 from home:eeich:branches:science - Fix CVEs: * CVE-2021-46244 (bsc#1195215) Compound-datatypes-may-not-have-members-of-size-0.patch * CVE-2018-13867 (bsc#1101906) Validate-location-offset-of-the-accumulated-metadata-when-comparing.patch * CVE-2018-16438 (bsc#1107069) Make-sure-info-block-for-external-links-has-at-least-3-bytes.patch * CVE-2020-10812 (bsc#1167400) Hot-fix-for-CVE-2020-10812.patch * CVE-2021-45830 (bsc#1194375) H5O_fsinfo_decode-Make-more-resilient-to-out-of-bounds-read.patch * CVE-2019-8396 (bsc#1125882) H5O__pline_decode-Make-more-resilient-to-out-of-bounds-read.patch * CVE-2018-11205 (bsc#1093663) Pass-compact-chunk-size-info-to-ensure-requested-elements-are-within-bounds.patch * CVE-2021-46242 (bsc#1195212) When-evicting-driver-info-block-NULL-the-corresponding-entry.patch * CVE-2021-45833 (bsc#1194366) Report-error-if-dimensions-of-chunked-storage-in-data-layout-2.patch * CVE-2018-14031 (bsc#1101475) H5O_dtype_decode_helper-Parent-of-enum-needs-to-have-same-size-as-enum-itself.patch * CVE-2018-17439 (bsc#1111598) H5IMget_image_info-H5Sget_simple_extent_dims-does-not-exceed-array-size.patch - Fix an error message: Fix-error-message-not-the-name-but-the-link-information-is-parsed.patch OBS-URL: https://build.opensuse.org/request/show/1030627 OBS-URL: https://build.opensuse.org/package/show/science/hdf5?expand=0&rev=159 --- ...types-may-not-have-members-of-size-0.patch | 51 ++++ ...e-but-the-link-information-is-parsed.patch | 26 ++ ...tent_dims-does-not-exceed-array-size.patch | 33 +++ ...more-resilient-to-out-of-bounds-read.patch | 85 ++++++ ...eds-to-have-same-size-as-enum-itself.patch | 35 +++ ...more-resilient-to-out-of-bounds-read.patch | 76 ++++++ Hot-fix-for-CVE-2020-10812.patch | 43 +++ ...-external-links-has-at-least-3-bytes.patch | 34 +++ ...requested-elements-are-within-bounds.patch | 258 ++++++++++++++++++ ...-of-chunked-storage-in-data-layout-2.patch | 48 ++++ ...-accumulated-metadata-when-comparing.patch | 96 +++++++ ...o-block-NULL-the-corresponding-entry.patch | 31 +++ hdf5.changes | 29 ++ hdf5.spec | 23 ++ 14 files changed, 868 insertions(+) create mode 100644 Compound-datatypes-may-not-have-members-of-size-0.patch create mode 100644 Fix-error-message-not-the-name-but-the-link-information-is-parsed.patch create mode 100644 H5IMget_image_info-H5Sget_simple_extent_dims-does-not-exceed-array-size.patch create mode 100644 H5O__pline_decode-Make-more-resilient-to-out-of-bounds-read.patch create mode 100644 H5O_dtype_decode_helper-Parent-of-enum-needs-to-have-same-size-as-enum-itself.patch create mode 100644 H5O_fsinfo_decode-Make-more-resilient-to-out-of-bounds-read.patch create mode 100644 Hot-fix-for-CVE-2020-10812.patch create mode 100644 Make-sure-info-block-for-external-links-has-at-least-3-bytes.patch create mode 100644 Pass-compact-chunk-size-info-to-ensure-requested-elements-are-within-bounds.patch create mode 100644 Report-error-if-dimensions-of-chunked-storage-in-data-layout-2.patch create mode 100644 Validate-location-offset-of-the-accumulated-metadata-when-comparing.patch create mode 100644 When-evicting-driver-info-block-NULL-the-corresponding-entry.patch diff --git a/Compound-datatypes-may-not-have-members-of-size-0.patch b/Compound-datatypes-may-not-have-members-of-size-0.patch new file mode 100644 index 0000000..12156d1 --- /dev/null +++ b/Compound-datatypes-may-not-have-members-of-size-0.patch @@ -0,0 +1,51 @@ +From: Egbert Eich +Date: Wed Oct 5 15:47:54 2022 +0200 +Subject: Compound datatypes may not have members of size 0 +Patch-mainline: Not yet +Git-repo: ssh://eich@192.168.122.1:/home/eich/sources/HPC/hdf5 +Git-commit: 88ea94d38fdfecba173dbea18502a5f82a46601b +References: + +A member size of 0 may lead to an FPE later on as reported in +CVE-2021-46244. To avoid this, check for this as soon as the +member is decoded. +This should probably be done in H5O_dtype_decode_helper() already, +however it is not clear whether all sizes are expected to be != 0. +This fixes CVE-2021-46244. + +Signed-off-by: Egbert Eich +Signed-off-by: Egbert Eich +--- + src/H5Odtype.c | 6 ++++++ + src/H5T.c | 2 ++ + 2 files changed, 8 insertions(+) +diff --git a/src/H5Odtype.c b/src/H5Odtype.c +index 9af79f4e9a..d35fc65322 100644 +--- a/src/H5Odtype.c ++++ b/src/H5Odtype.c +@@ -333,6 +333,12 @@ H5O__dtype_decode_helper(unsigned *ioflags /*in,out*/, const uint8_t **pp, H5T_t + H5MM_xfree(dt->shared->u.compnd.memb); + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "unable to decode member type") + } /* end if */ ++ if (temp_type->shared->size == 0) { ++ for (j = 0; j <= i; j++) ++ H5MM_xfree(dt->shared->u.compnd.memb[j].name); ++ H5MM_xfree(dt->shared->u.compnd.memb); ++ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "invalid field size in member type") ++ } + + /* Upgrade the version if we can and it is necessary */ + if (can_upgrade && temp_type->shared->version > version) { +diff --git a/src/H5T.c b/src/H5T.c +index 3bb220ac26..04b96c5676 100644 +--- a/src/H5T.c ++++ b/src/H5T.c +@@ -3591,6 +3591,8 @@ H5T__complete_copy(H5T_t *new_dt, const H5T_t *old_dt, H5T_shared_t *reopened_fo + if (new_dt->shared->u.compnd.memb[i].type->shared->size != + old_dt->shared->u.compnd.memb[old_match].type->shared->size) { + /* Adjust the size of the member */ ++ if (old_dt->shared->u.compnd.memb[old_match].size == 0) ++ HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "invalid field size in datatype") + new_dt->shared->u.compnd.memb[i].size = + (old_dt->shared->u.compnd.memb[old_match].size * tmp->shared->size) / + old_dt->shared->u.compnd.memb[old_match].type->shared->size; diff --git a/Fix-error-message-not-the-name-but-the-link-information-is-parsed.patch b/Fix-error-message-not-the-name-but-the-link-information-is-parsed.patch new file mode 100644 index 0000000..98b5728 --- /dev/null +++ b/Fix-error-message-not-the-name-but-the-link-information-is-parsed.patch @@ -0,0 +1,26 @@ +From: Egbert Eich +Date: Sun Oct 9 08:08:24 2022 +0200 +Subject: Fix error message: not the name but the link information is parsed +Patch-mainline: Not yet +Git-repo: ssh://eich@192.168.122.1:/home/eich/sources/HPC/hdf5 +Git-commit: 7b0b8bc5703ace47aec51d7f60c1149cd3e383b1 +References: + +Signed-off-by: Egbert Eich +Signed-off-by: Egbert Eich +--- + src/H5Olink.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) +diff --git a/src/H5Olink.c b/src/H5Olink.c +index 51c44a36b0..ee2a413dc1 100644 +--- a/src/H5Olink.c ++++ b/src/H5Olink.c +@@ -245,7 +245,7 @@ H5O__link_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSE + /* Make sure that length doesn't exceed buffer size, which could + occur when the file is corrupted */ + if (p + len > p_end) +- HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "name length causes read past end of buffer") ++ HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "link information length causes read past end of buffer") + + if (NULL == (lnk->u.ud.udata = H5MM_malloc((size_t)len))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") diff --git a/H5IMget_image_info-H5Sget_simple_extent_dims-does-not-exceed-array-size.patch b/H5IMget_image_info-H5Sget_simple_extent_dims-does-not-exceed-array-size.patch new file mode 100644 index 0000000..ebfde53 --- /dev/null +++ b/H5IMget_image_info-H5Sget_simple_extent_dims-does-not-exceed-array-size.patch @@ -0,0 +1,33 @@ +From: Egbert Eich +Date: Tue Sep 27 10:29:56 2022 +0200 +Subject: H5IMget_image_info: H5Sget_simple_extent_dims() does not exceed array size +Patch-mainline: Not yet +Git-repo: ssh://eich@192.168.122.1:/home/eich/sources/HPC/hdf5 +Git-commit: c1baab0937c8956a15efc41240f68d573c7b7324 +References: + +Malformed hdf5 files may provide more dimensions than the array dim[] is +able to hold. Check number of elements first by calling +H5Sget_simple_extent_dims() with NULL for both 'dims' and 'maxdims' arguments. +This will cause the function to return only the number of dimensions. + +This fixes CVE-2018-17439 + +Signed-off-by: Egbert Eich +Signed-off-by: Egbert Eich +--- + hl/src/H5IM.c | 2 ++ + 1 file changed, 2 insertions(+) +diff --git a/hl/src/H5IM.c b/hl/src/H5IM.c +index ff10d573c7..e37c696e25 100644 +--- a/hl/src/H5IM.c ++++ b/hl/src/H5IM.c +@@ -283,6 +283,8 @@ H5IMget_image_info(hid_t loc_id, const char *dset_name, hsize_t *width, hsize_t + if ((sid = H5Dget_space(did)) < 0) + goto out; + ++ if (H5Sget_simple_extent_dims(sid, NULL, NULL) > IMAGE24_RANK) ++ goto out; + /* Get dimensions */ + if (H5Sget_simple_extent_dims(sid, dims, NULL) < 0) + goto out; diff --git a/H5O__pline_decode-Make-more-resilient-to-out-of-bounds-read.patch b/H5O__pline_decode-Make-more-resilient-to-out-of-bounds-read.patch new file mode 100644 index 0000000..2ab5ccd --- /dev/null +++ b/H5O__pline_decode-Make-more-resilient-to-out-of-bounds-read.patch @@ -0,0 +1,85 @@ +From: Egbert Eich +Date: Tue Oct 4 23:09:01 2022 +0200 +Subject: H5O__pline_decode() Make more resilient to out-of-bounds read +Patch-mainline: Not yet +Git-repo: ssh://eich@192.168.122.1:/home/eich/sources/HPC/hdf5 +Git-commit: 35b798ca7542ce45ef016859b8e70d57b7f89cfe +References: + +Malformed hdf5 files may have trunkated content which does not match +the expected size. This function attempts to decode these it will read +past the end of the allocated space which may lead to a crash. Make sure +each element is within bounds before reading. + +This fixes CVE-2019-8396. + +Signed-off-by: Egbert Eich +Signed-off-by: Egbert Eich +--- + src/H5Opline.c | 17 +++++++++++++++-- + src/H5private.h | 3 +++ + 2 files changed, 18 insertions(+), 2 deletions(-) +diff --git a/src/H5Opline.c b/src/H5Opline.c +index ffc4557ffc..a532aa4512 100644 +--- a/src/H5Opline.c ++++ b/src/H5Opline.c +@@ -110,6 +110,14 @@ H5FL_DEFINE(H5O_pline_t); + * + *------------------------------------------------------------------------- + */ ++static char err[] = "ran off the end of the buffer: current p = %p, p_end = %p"; ++ ++#define VERIFY_LIMIT(p,s,l) \ ++ if (p + s - 1 > l) { \ ++ HCOMMON_ERROR(H5E_RESOURCE, H5E_NOSPACE, err, p + s, l); \ ++ HGOTO_DONE(NULL) \ ++ }; ++ + static void * + H5O__pline_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, + unsigned H5_ATTR_UNUSED *ioflags, size_t p_size, const uint8_t *p) +@@ -159,6 +167,7 @@ H5O__pline_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, unsign + /* Decode filters */ + for (i = 0, filter = &pline->filter[0]; i < pline->nused; i++, filter++) { + /* Filter ID */ ++ VERIFY_LIMIT(p, 6, p_end) /* 6 bytes minimum */ + UINT16DECODE(p, filter->id); + + /* Length of filter name */ +@@ -168,6 +177,7 @@ H5O__pline_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, unsign + UINT16DECODE(p, name_length); + if (pline->version == H5O_PLINE_VERSION_1 && name_length % 8) + HGOTO_ERROR(H5E_PLINE, H5E_CANTLOAD, NULL, "filter name length is not a multiple of eight") ++ VERIFY_LIMIT(p, 4, p_end) /* with name_length 4 bytes to go */ + } /* end if */ + + /* Filter flags */ +@@ -179,9 +189,12 @@ H5O__pline_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, unsign + /* Filter name, if there is one */ + if (name_length) { + size_t actual_name_length; /* Actual length of name */ +- ++ size_t len = (size_t)(p_end - p + 1); + /* Determine actual name length (without padding, but with null terminator) */ +- actual_name_length = HDstrlen((const char *)p) + 1; ++ actual_name_length = HDstrnlen((const char *)p, len); ++ if (actual_name_length == len) ++ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "filter name not null terminated") ++ actual_name_length += 1; /* include \0 byte */ + HDassert(actual_name_length <= name_length); + + /* Allocate space for the filter name, or use the internal buffer */ +diff --git a/src/H5private.h b/src/H5private.h +index bc00f120d2..3285c36441 100644 +--- a/src/H5private.h ++++ b/src/H5private.h +@@ -1485,6 +1485,9 @@ H5_DLL H5_ATTR_CONST int Nflock(int fd, int operation); + #ifndef HDstrlen + #define HDstrlen(S) strlen(S) + #endif ++#ifndef HDstrnlen ++#define HDstrnlen(S,L) strnlen(S,L) ++#endif + #ifndef HDstrncat + #define HDstrncat(X, Y, Z) strncat(X, Y, Z) + #endif diff --git a/H5O_dtype_decode_helper-Parent-of-enum-needs-to-have-same-size-as-enum-itself.patch b/H5O_dtype_decode_helper-Parent-of-enum-needs-to-have-same-size-as-enum-itself.patch new file mode 100644 index 0000000..4cef941 --- /dev/null +++ b/H5O_dtype_decode_helper-Parent-of-enum-needs-to-have-same-size-as-enum-itself.patch @@ -0,0 +1,35 @@ +From: Egbert Eich +Date: Wed Sep 28 14:54:58 2022 +0200 +Subject: H5O_dtype_decode_helper: Parent of enum needs to have same size as enum itself +Patch-mainline: Not yet +Git-repo: ssh://eich@192.168.122.1:/home/eich/sources/HPC/hdf5 +Git-commit: d39a27113ef75058f236b0606a74b4af5767c4e7 +References: + +The size of the enumeration values is determined by the size of the parent. +Functions accessing the enumeration values use the size of the enumartion +to determine the size of each element and how much data to copy. Thus the +size of the enumeration and its parent need to match. +Check here to avoid unpleasant surprises later. + +This fixes CVE-2018-14031. + +Signed-off-by: Egbert Eich +Signed-off-by: Egbert Eich +--- + src/H5Odtype.c | 3 +++ + 1 file changed, 3 insertions(+) +diff --git a/src/H5Odtype.c b/src/H5Odtype.c +index 9af79f4e9a..dc2b904362 100644 +--- a/src/H5Odtype.c ++++ b/src/H5Odtype.c +@@ -472,6 +472,9 @@ H5O__dtype_decode_helper(unsigned *ioflags /*in,out*/, const uint8_t **pp, H5T_t + if (H5O__dtype_decode_helper(ioflags, pp, dt->shared->parent) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "unable to decode parent datatype") + ++ if (dt->shared->parent->shared->size != dt->shared->size) ++ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "ENUM size does not match parent") ++ + /* Check if the parent of this enum has a version greater than the + * enum itself. */ + H5O_DTYPE_CHECK_VERSION(dt, version, dt->shared->parent->shared->version, ioflags, "enum", FAIL) diff --git a/H5O_fsinfo_decode-Make-more-resilient-to-out-of-bounds-read.patch b/H5O_fsinfo_decode-Make-more-resilient-to-out-of-bounds-read.patch new file mode 100644 index 0000000..70849d2 --- /dev/null +++ b/H5O_fsinfo_decode-Make-more-resilient-to-out-of-bounds-read.patch @@ -0,0 +1,76 @@ +From: Egbert Eich +Date: Wed Oct 5 07:17:24 2022 +0200 +Subject: H5O_fsinfo_decode() Make more resilient to out-of-bounds read +Patch-mainline: Not yet +Git-repo: ssh://eich@192.168.122.1:/home/eich/sources/HPC/hdf5 +Git-commit: 8aee14b3a19858a08e3fabdef6ff925b47d4ce2c +References: + +Malformed hdf5 files may have trunkated content which does not match +the expected size. This function attempts to decode these it will read +past the end of the allocated space which may lead to a crash. Make sure +each element is within bounds before reading. + +This fixes CVE-2021-45830. + +Signed-off-by: Egbert Eich +Additions +Signed-off-by: Egbert Eich +--- + src/H5Ofsinfo.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) +diff --git a/src/H5Ofsinfo.c b/src/H5Ofsinfo.c +index 9f6514a291..15cbb5ae7b 100644 +--- a/src/H5Ofsinfo.c ++++ b/src/H5Ofsinfo.c +@@ -88,6 +88,13 @@ H5FL_DEFINE_STATIC(H5O_fsinfo_t); + * + *------------------------------------------------------------------------- + */ ++static char err[] = "ran off end of input buffer while decoding"; ++#define VERIFY_LIMIT(p,s,l) \ ++ if (p + s - 1 > l) { \ ++ HCOMMON_ERROR(H5E_RESOURCE, H5E_NOSPACE, err); \ ++ HGOTO_DONE(NULL) \ ++ } ++ + static void * + H5O__fsinfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, + unsigned H5_ATTR_UNUSED *ioflags, size_t p_size, const uint8_t *p) +@@ -112,6 +119,7 @@ H5O__fsinfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU + fsinfo->fs_addr[ptype - 1] = HADDR_UNDEF; + + /* Version of message */ ++ VERIFY_LIMIT(p,1,p_end) + vers = *p++; + + if (vers == H5O_FSINFO_VERSION_0) { +@@ -125,6 +133,7 @@ H5O__fsinfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU + fsinfo->pgend_meta_thres = H5F_FILE_SPACE_PGEND_META_THRES; + fsinfo->eoa_pre_fsm_fsalloc = HADDR_UNDEF; + ++ VERIFY_LIMIT(p, 1 + H5F_SIZEOF_SIZE(f), p_end); + strategy = (H5F_file_space_type_t)*p++; /* File space strategy */ + H5F_DECODE_LENGTH(f, p, threshold); /* Free-space section threshold */ + +@@ -170,6 +179,7 @@ H5O__fsinfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU + HDassert(vers >= H5O_FSINFO_VERSION_1); + + fsinfo->version = vers; ++ VERIFY_LIMIT(p, 1 + 1 + 2 * H5F_SIZEOF_SIZE(f) + 2 + H5F_SIZEOF_ADDR(f), p_end); + fsinfo->strategy = (H5F_fspace_strategy_t)*p++; /* File space strategy */ + fsinfo->persist = *p++; /* Free-space persist or not */ + H5F_DECODE_LENGTH(f, p, fsinfo->threshold); /* Free-space section threshold */ +@@ -181,9 +191,11 @@ H5O__fsinfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU + + /* Decode addresses of free space managers, if persisting */ + if (fsinfo->persist) +- for (ptype = H5F_MEM_PAGE_SUPER; ptype < H5F_MEM_PAGE_NTYPES; ptype++) ++ for (ptype = H5F_MEM_PAGE_SUPER; ptype < H5F_MEM_PAGE_NTYPES; ptype++) { ++ VERIFY_LIMIT(p, H5F_SIZEOF_SIZE(f), p_end); + H5F_addr_decode(f, &p, &(fsinfo->fs_addr[ptype - 1])); + ++ } + fsinfo->mapped = FALSE; + } + diff --git a/Hot-fix-for-CVE-2020-10812.patch b/Hot-fix-for-CVE-2020-10812.patch new file mode 100644 index 0000000..dc75465 --- /dev/null +++ b/Hot-fix-for-CVE-2020-10812.patch @@ -0,0 +1,43 @@ +From: Egbert Eich +Date: Wed Oct 5 09:44:02 2022 +0200 +Subject: Hot fix for CVE-2020-10812 +Patch-mainline: Not yet +Git-repo: ssh://eich@192.168.122.1:/home/eich/sources/HPC/hdf5 +Git-commit: 2465fc41d208d57eb0d7d025286a81664148fbaf +References: + +CVE-2020-10812 unveils a more fundamental design flaw in H5F__dest(): +this function returns FAIL if one of multiple operations fail (in this +case H5AC_prep_for_file_close()) while it still proceeds to prepare the +close operation, free the 'shared' member in struct H5F_t and ulimately +deallocate the structure itself. +When H5F__dest() signals back FAIL to the caller, the caller itself +(H5F_try_close() in this case) will fail. This failure is signalled +up the stack, thus the file will not be considered closed and another +attempt will be made to close it - latest in the exit handler. +The next attempt to close will however need the already deallocated +H5F_t structure and the H5T_shared_t structure in its 'shared' member, +however. +This fix papers over the failure of H5AC_prep_for_file_close() by not +changing the return status of H5F__dest() to fail. There are numerous +other opportunities where this will happen. +This may call for a more fundamental solution. + +Signed-off-by: Egbert Eich +Signed-off-by: Egbert Eich +--- + src/H5Fint.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) +diff --git a/src/H5Fint.c b/src/H5Fint.c +index 9b5613972f..01faf33495 100644 +--- a/src/H5Fint.c ++++ b/src/H5Fint.c +@@ -1413,7 +1413,7 @@ H5F__dest(H5F_t *f, hbool_t flush) + */ + if (H5AC_prep_for_file_close(f) < 0) + /* Push error, but keep going */ +- HDONE_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "metadata cache prep for close failed") ++ HDONE_ERROR(H5E_FILE, H5E_CANTFLUSH, ret_value, "metadata cache prep for close failed") + + /* Flush at this point since the file will be closed (phase 2). + * Only try to flush the file if it was opened with write access, and if diff --git a/Make-sure-info-block-for-external-links-has-at-least-3-bytes.patch b/Make-sure-info-block-for-external-links-has-at-least-3-bytes.patch new file mode 100644 index 0000000..ed21de6 --- /dev/null +++ b/Make-sure-info-block-for-external-links-has-at-least-3-bytes.patch @@ -0,0 +1,34 @@ +From: Egbert Eich +Date: Sun Oct 9 08:07:23 2022 +0200 +Subject: Make sure info block for external links has at least 3 bytes +Patch-mainline: Not yet +Git-repo: ssh://eich@192.168.122.1:/home/eich/sources/HPC/hdf5 +Git-commit: 082bfe392b04b1137da9eabd1ecac76c212ab385 +References: + +According to the specification, the information block for external links +contains 1 byte of version/flag information and two 0 terminated strings +for the object linked to and the full path. +Although not very useful, the minimum string length for each would be one +byte. + +This fixes CVE-2018-16438. + +Signed-off-by: Egbert Eich +Signed-off-by: Egbert Eich +--- + src/H5Olink.c | 2 ++ + 1 file changed, 2 insertions(+) +diff --git a/src/H5Olink.c b/src/H5Olink.c +index 51c44a36b0..074744b022 100644 +--- a/src/H5Olink.c ++++ b/src/H5Olink.c +@@ -241,6 +241,8 @@ H5O__link_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSE + /* A UD link. Get the user-supplied data */ + UINT16DECODE(p, len) + lnk->u.ud.size = len; ++ if (lnk->type == H5L_TYPE_EXTERNAL && len < 3) ++ HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "external link information lenght < 3") + if (len > 0) { + /* Make sure that length doesn't exceed buffer size, which could + occur when the file is corrupted */ diff --git a/Pass-compact-chunk-size-info-to-ensure-requested-elements-are-within-bounds.patch b/Pass-compact-chunk-size-info-to-ensure-requested-elements-are-within-bounds.patch new file mode 100644 index 0000000..fe85f12 --- /dev/null +++ b/Pass-compact-chunk-size-info-to-ensure-requested-elements-are-within-bounds.patch @@ -0,0 +1,258 @@ +From: Egbert Eich +Date: Sat Oct 1 15:13:52 2022 +0200 +Subject: Pass compact chunk size info to ensure requested elements are within bounds +Patch-mainline: Not yet +Git-repo: ssh://eich@192.168.122.1:/home/eich/sources/HPC/hdf5 +Git-commit: 18300944261a9fa8f0087f99d9176f3757b1ec38 +References: + +To avoid reading/writing elements out of bounds of a compact chunk, pass +size info and check whether all elements are within the size before attempting +to read/write these elements. Such accesses can occur when accessing malformed +hdf5 files. + +This fixes CVE-2018-11205 + +Signed-off-by: Egbert Eich +Signed-off-by: Egbert Eich +--- + src/H5Dchunk.c | 34 +++++++++++++++++++++++++++------- + src/H5Dcompact.c | 5 +++++ + src/H5Dpkg.h | 1 + + 3 files changed, 33 insertions(+), 7 deletions(-) +diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c +index e6bf26ce89..94ad392cb7 100644 +--- a/src/H5Dchunk.c ++++ b/src/H5Dchunk.c +@@ -128,6 +128,7 @@ typedef struct H5D_rdcc_ent_t { + H5F_block_t chunk_block; /*offset/length of chunk in file */ + hsize_t chunk_idx; /*index of chunk in dataset */ + uint8_t * chunk; /*the unfiltered chunk data */ ++ size_t size; /*size of chunk */ + unsigned idx; /*index in hash table */ + struct H5D_rdcc_ent_t *next; /*next item in doubly-linked list */ + struct H5D_rdcc_ent_t *prev; /*previous item in doubly-linked list */ +@@ -303,7 +304,7 @@ static unsigned H5D__chunk_hash_val(const H5D_shared_t *shared, const hsize_t *s + static herr_t H5D__chunk_flush_entry(const H5D_t *dset, H5D_rdcc_ent_t *ent, hbool_t reset); + static herr_t H5D__chunk_cache_evict(const H5D_t *dset, H5D_rdcc_ent_t *ent, hbool_t flush); + static void * H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, hbool_t relax, +- hbool_t prev_unfilt_chunk); ++ hbool_t prev_unfilt_chunk, size_t *ret_size); + static herr_t H5D__chunk_unlock(const H5D_io_info_t *io_info, const H5D_chunk_ud_t *udata, hbool_t dirty, + void *chunk, uint32_t naccessed); + static herr_t H5D__chunk_cache_prune(const H5D_t *dset, size_t size); +@@ -2480,6 +2481,7 @@ H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_ + uint32_t src_accessed_bytes = 0; /* Total accessed size in a chunk */ + hbool_t skip_missing_chunks = FALSE; /* Whether to skip missing chunks */ + herr_t ret_value = SUCCEED; /*return value */ ++ size_t chunk_size = 0; + + FUNC_ENTER_STATIC + +@@ -2565,11 +2567,12 @@ H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_ + src_accessed_bytes = chunk_info->chunk_points * (uint32_t)type_info->src_type_size; + + /* Lock the chunk into the cache */ +- if (NULL == (chunk = H5D__chunk_lock(io_info, &udata, FALSE, FALSE))) ++ if (NULL == (chunk = H5D__chunk_lock(io_info, &udata, FALSE, FALSE, &chunk_size))) + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk") + + /* Set up the storage buffer information for this chunk */ + cpt_store.compact.buf = chunk; ++ cpt_store.compact.size = chunk_size; + + /* Point I/O info at contiguous I/O info for this chunk */ + chk_io_info = &cpt_io_info; +@@ -2629,6 +2632,7 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize + hbool_t cpt_dirty; /* Temporary placeholder for compact storage "dirty" flag */ + uint32_t dst_accessed_bytes = 0; /* Total accessed size in a chunk */ + herr_t ret_value = SUCCEED; /* Return value */ ++ size_t chunk_size; + + FUNC_ENTER_STATIC + +@@ -2699,11 +2703,12 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize + entire_chunk = FALSE; + + /* Lock the chunk into the cache */ +- if (NULL == (chunk = H5D__chunk_lock(io_info, &udata, entire_chunk, FALSE))) ++ if (NULL == (chunk = H5D__chunk_lock(io_info, &udata, entire_chunk, FALSE, &chunk_size))) + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk") + + /* Set up the storage buffer information for this chunk */ + cpt_store.compact.buf = chunk; ++ cpt_store.compact.size = chunk_size; + + /* Point I/O info at main I/O info for this chunk */ + chk_io_info = &cpt_io_info; +@@ -3714,7 +3719,7 @@ done: + *------------------------------------------------------------------------- + */ + static void * +-H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, hbool_t relax, hbool_t prev_unfilt_chunk) ++H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, hbool_t relax, hbool_t prev_unfilt_chunk, size_t *ret_size) + { + const H5D_t * dset = io_info->dset; /* Local pointer to the dataset info */ + const H5O_pline_t *pline = +@@ -3731,6 +3736,7 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, hbool_t rel + hbool_t disable_filters = FALSE; /* Whether to disable filters (when adding to cache) */ + void * chunk = NULL; /*the file chunk */ + void * ret_value = NULL; /* Return value */ ++ size_t chunk_size_ret = 0; + + FUNC_ENTER_STATIC + +@@ -3796,6 +3802,7 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, hbool_t rel + ent->chunk = (uint8_t *)H5D__chunk_mem_xfree(ent->chunk, old_pline); + ent->chunk = (uint8_t *)chunk; + chunk = NULL; ++ ent->size = chunk_size; + + /* Mark the chunk as having filters disabled as well as "newly + * disabled" so it is inserted on flush */ +@@ -3823,6 +3830,7 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, hbool_t rel + ent->chunk = (uint8_t *)H5D__chunk_mem_xfree(ent->chunk, old_pline); + ent->chunk = (uint8_t *)chunk; + chunk = NULL; ++ ent->size = chunk_size; + + /* Mark the chunk as having filters enabled */ + ent->edge_chunk_state &= ~(H5D_RDCC_DISABLE_FILTERS | H5D_RDCC_NEWLY_DISABLED_FILTERS); +@@ -3902,6 +3910,7 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, hbool_t rel + /* In the case that some dataset functions look through this data, + * clear it to all 0s. */ + HDmemset(chunk, 0, chunk_size); ++ chunk_size_ret = chunk_size; + } /* end if */ + else { + /* +@@ -3924,6 +3933,7 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, hbool_t rel + my_chunk_alloc, chunk) < 0) + HGOTO_ERROR(H5E_IO, H5E_READERROR, NULL, "unable to read raw data chunk") + ++ chunk_size_ret = my_chunk_alloc; + if (old_pline && old_pline->nused) { + H5Z_EDC_t err_detect; /* Error detection info */ + H5Z_cb_t filter_cb; /* I/O filter callback function */ +@@ -3937,6 +3947,7 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, hbool_t rel + if (H5Z_pipeline(old_pline, H5Z_FLAG_REVERSE, &(udata->filter_mask), err_detect, + filter_cb, &my_chunk_alloc, &buf_alloc, &chunk) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTFILTER, NULL, "data pipeline read failed") ++ chunk_size_ret = buf_alloc; + + /* Reallocate chunk if necessary */ + if (udata->new_unfilt_chunk) { +@@ -3947,6 +3958,7 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, hbool_t rel + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed for raw data chunk") + } /* end if */ ++ chunk_size_ret = my_chunk_alloc; + H5MM_memcpy(chunk, tmp_chunk, chunk_size); + (void)H5D__chunk_mem_xfree(tmp_chunk, old_pline); + } /* end if */ +@@ -3967,6 +3979,7 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, hbool_t rel + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed for raw data chunk") + ++ chunk_size_ret = chunk_size; + if (H5P_is_fill_value_defined(fill, &fill_status) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't tell if fill value defined") + +@@ -4032,6 +4045,7 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, hbool_t rel + H5_CHECKED_ASSIGN(ent->rd_count, uint32_t, chunk_size, size_t); + H5_CHECKED_ASSIGN(ent->wr_count, uint32_t, chunk_size, size_t); + ent->chunk = (uint8_t *)chunk; ++ ent->size = chunk_size_ret; + + /* Add it to the cache */ + HDassert(NULL == rdcc->slot[udata->idx_hint]); +@@ -4065,6 +4079,7 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, hbool_t rel + HDassert(!ent->locked); + ent->locked = TRUE; + chunk = ent->chunk; ++ chunk_size_ret = ent->size; + } /* end if */ + else + /* +@@ -4076,6 +4091,8 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, hbool_t rel + + /* Set return value */ + ret_value = chunk; ++ if (ret_size != NULL) ++ *ret_size = chunk_size_ret; + + done: + /* Release the fill buffer info, if it's been initialized */ +@@ -4084,8 +4101,11 @@ done: + + /* Release the chunk allocated, on error */ + if (!ret_value) +- if (chunk) ++ if (chunk) { + chunk = H5D__chunk_mem_xfree(chunk, pline); ++ if (ret_size != NULL) ++ *ret_size = 0; ++ } + + FUNC_LEAVE_NOAPI(ret_value) + } /* end H5D__chunk_lock() */ +@@ -4884,7 +4904,7 @@ H5D__chunk_update_old_edge_chunks(H5D_t *dset, hsize_t old_dim[]) + if (H5F_addr_defined(chk_udata.chunk_block.offset) || (UINT_MAX != chk_udata.idx_hint)) { + /* Lock the chunk into cache. H5D__chunk_lock will take care of + * updating the chunk to no longer be an edge chunk. */ +- if (NULL == (chunk = (void *)H5D__chunk_lock(&chk_io_info, &chk_udata, FALSE, TRUE))) ++ if (NULL == (chunk = (void *)H5D__chunk_lock(&chk_io_info, &chk_udata, FALSE, TRUE, NULL))) + HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "unable to lock raw data chunk") + + /* Unlock the chunk */ +@@ -5274,7 +5294,7 @@ H5D__chunk_prune_fill(H5D_chunk_it_ud1_t *udata, hbool_t new_unfilt_chunk) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSELECT, FAIL, "unable to select hyperslab") + + /* Lock the chunk into the cache, to get a pointer to the chunk buffer */ +- if (NULL == (chunk = (void *)H5D__chunk_lock(io_info, &chk_udata, FALSE, FALSE))) ++ if (NULL == (chunk = (void *)H5D__chunk_lock(io_info, &chk_udata, FALSE, FALSE, NULL))) + HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "unable to lock raw data chunk") + + /* Fill the selection in the memory buffer */ +diff --git a/src/H5Dcompact.c b/src/H5Dcompact.c +index b78693660d..21c37e8a08 100644 +--- a/src/H5Dcompact.c ++++ b/src/H5Dcompact.c +@@ -245,6 +245,7 @@ H5D__compact_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t H5_ATTR + FUNC_ENTER_STATIC_NOERR + + io_info->store->compact.buf = io_info->dset->shared->layout.storage.u.compact.buf; ++ io_info->store->compact.size = io_info->dset->shared->layout.storage.u.compact.size; + io_info->store->compact.dirty = &io_info->dset->shared->layout.storage.u.compact.dirty; + + FUNC_LEAVE_NOAPI(SUCCEED) +@@ -278,6 +279,8 @@ H5D__compact_readvv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t * + FUNC_ENTER_STATIC + + HDassert(io_info); ++ if (io_info->store->compact.size < *(dset_offset_arr + dset_max_nseq - 1) + *(dset_size_arr + dset_max_nseq - 1)) ++ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "source size less than requested data") + + /* Use the vectorized memory copy routine to do actual work */ + if ((ret_value = H5VM_memcpyvv(io_info->u.rbuf, mem_max_nseq, mem_curr_seq, mem_size_arr, mem_offset_arr, +@@ -320,6 +323,8 @@ H5D__compact_writevv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t + FUNC_ENTER_STATIC + + HDassert(io_info); ++ if (io_info->store->compact.size < *(dset_offset_arr + dset_max_nseq - 1) + *(dset_size_arr + dset_max_nseq - 1)) ++ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "source size less than requested data") + + /* Use the vectorized memory copy routine to do actual work */ + if ((ret_value = H5VM_memcpyvv(io_info->store->compact.buf, dset_max_nseq, dset_curr_seq, dset_size_arr, +diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h +index 64692c5d1d..8a4acd62e3 100644 +--- a/src/H5Dpkg.h ++++ b/src/H5Dpkg.h +@@ -196,6 +196,7 @@ typedef struct { + typedef struct { + void * buf; /* Buffer for compact dataset */ + hbool_t *dirty; /* Pointer to dirty flag to mark */ ++ size_t size; /* Buffer size for compact dataset */ + } H5D_compact_storage_t; + + typedef union H5D_storage_t { diff --git a/Report-error-if-dimensions-of-chunked-storage-in-data-layout-2.patch b/Report-error-if-dimensions-of-chunked-storage-in-data-layout-2.patch new file mode 100644 index 0000000..f3902a1 --- /dev/null +++ b/Report-error-if-dimensions-of-chunked-storage-in-data-layout-2.patch @@ -0,0 +1,48 @@ +From: Egbert Eich +Date: Wed Sep 28 19:11:16 2022 +0200 +Subject: Report error if dimensions of chunked storage in data layout < 2 +Patch-mainline: Not yet +Git-repo: ssh://eich@192.168.122.1:/home/eich/sources/HPC/hdf5 +Git-commit: 34b621424504265cff3c33cf634a70efb52db180 +References: + +For Data Layout Messages version 1 & 2 the specification state +that the value stored in the data field is 1 greater than the +number of dimensions in the dataspace. For version 3 this is +not explicitly stated but the implementation suggests it to be +the case. +Thus the set value needs to be at least 2. For dimensionality +< 2 an out-of-bounds access occurs as in CVE-2021-45833. + +This fixes CVE-2021-45833. + +Signed-off-by: Egbert Eich +Signed-off-by: Egbert Eich +--- + src/H5Olayout.c | 7 +++++++ + 1 file changed, 7 insertions(+) +diff --git a/src/H5Olayout.c b/src/H5Olayout.c +index c939e72744..9fa9e36e8c 100644 +--- a/src/H5Olayout.c ++++ b/src/H5Olayout.c +@@ -168,6 +168,10 @@ H5O__layout_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU + p += ndims * 4; /* Skip over dimension sizes (32-bit quantities) */ + } /* end if */ + else { ++ if (ndims < 2) ++ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, ++ "bad dimensions for chunked storage") ++ + mesg->u.chunk.ndims = ndims; + for (u = 0; u < ndims; u++) + UINT32DECODE(p, mesg->u.chunk.dim[u]); +@@ -241,6 +245,9 @@ H5O__layout_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU + mesg->u.chunk.ndims = *p++; + if (mesg->u.chunk.ndims > H5O_LAYOUT_NDIMS) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "dimensionality is too large") ++ if (mesg->u.chunk.ndims < 2) ++ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, ++ "bad dimensions for chunked storage") + + /* B-tree address */ + H5F_addr_decode(f, &p, &(mesg->storage.u.chunk.idx_addr)); diff --git a/Validate-location-offset-of-the-accumulated-metadata-when-comparing.patch b/Validate-location-offset-of-the-accumulated-metadata-when-comparing.patch new file mode 100644 index 0000000..7833974 --- /dev/null +++ b/Validate-location-offset-of-the-accumulated-metadata-when-comparing.patch @@ -0,0 +1,96 @@ +From: Egbert Eich +Date: Mon Oct 10 08:43:44 2022 +0200 +Subject: Validate location (offset) of the accumulated metadata when comparing +Patch-mainline: Not yet +Git-repo: ssh://eich@192.168.122.1:/home/eich/sources/HPC/hdf5 +Git-commit: 2cf9918ae66f023a2b6d44eb591ee2ac479a6e53 +References: + +Initially, the accumulated metadata location is initialized to HADDR_UNDEF +- the highest available address. Bogus input files may provide a location +or size matching this value. Comparing this address against such bogus +values may provide false positives. This make sure, the value has been +initilized or fail the comparison early and let other parts of the +code deal with the bogus address/size. +Note: To avoid unnecessary checks, we have assumed that if the 'dirty' +member in the same structure is true the location is valid. + +This fixes CVE-2018-13867. + +Signed-off-by: Egbert Eich +Signed-off-by: Egbert Eich +--- + src/H5Faccum.c | 19 +++++++++++++------ + 1 file changed, 13 insertions(+), 6 deletions(-) +diff --git a/src/H5Faccum.c b/src/H5Faccum.c +index aed5812e63..73bd4b811e 100644 +--- a/src/H5Faccum.c ++++ b/src/H5Faccum.c +@@ -48,6 +48,7 @@ + #define H5F_ACCUM_THROTTLE 8 + #define H5F_ACCUM_THRESHOLD 2048 + #define H5F_ACCUM_MAX_SIZE (1024 * 1024) /* Max. accum. buf size (max. I/Os will be 1/2 this size) */ ++#define H5F_LOC_VALID(x) (x != HADDR_UNDEF) + + /******************/ + /* Local Typedefs */ +@@ -126,8 +127,9 @@ H5F__accum_read(H5F_shared_t *f_sh, H5FD_mem_t map_type, haddr_t addr, size_t si + HDassert(!accum->buf || (accum->alloc_size >= accum->size)); + + /* Current read adjoins or overlaps with metadata accumulator */ +- if (H5F_addr_overlap(addr, size, accum->loc, accum->size) || ((addr + size) == accum->loc) || +- (accum->loc + accum->size) == addr) { ++ if (H5F_LOC_VALID(accum->loc) && ++ (H5F_addr_overlap(addr, size, accum->loc, accum->size) || ((addr + size) == accum->loc) || ++ (accum->loc + accum->size) == addr)) { + size_t amount_before; /* Amount to read before current accumulator */ + haddr_t new_addr; /* New address of the accumulator buffer */ + size_t new_size; /* New size of the accumulator buffer */ +@@ -439,7 +441,8 @@ H5F__accum_write(H5F_shared_t *f_sh, H5FD_mem_t map_type, haddr_t addr, size_t s + /* Check if there is already metadata in the accumulator */ + if (accum->size > 0) { + /* Check if the new metadata adjoins the beginning of the current accumulator */ +- if ((addr + size) == accum->loc) { ++ if (H5F_LOC_VALID(accum->loc) ++ && (addr + size) == accum->loc) { + /* Check if we need to adjust accumulator size */ + if (H5F__accum_adjust(accum, file, H5F_ACCUM_PREPEND, size) < 0) + HGOTO_ERROR(H5E_IO, H5E_CANTRESIZE, FAIL, "can't adjust metadata accumulator") +@@ -464,7 +467,8 @@ H5F__accum_write(H5F_shared_t *f_sh, H5FD_mem_t map_type, haddr_t addr, size_t s + accum->dirty_off = 0; + } /* end if */ + /* Check if the new metadata adjoins the end of the current accumulator */ +- else if (addr == (accum->loc + accum->size)) { ++ else if (H5F_LOC_VALID(accum->loc) && ++ addr == (accum->loc + accum->size)) { + /* Check if we need to adjust accumulator size */ + if (H5F__accum_adjust(accum, file, H5F_ACCUM_APPEND, size) < 0) + HGOTO_ERROR(H5E_IO, H5E_CANTRESIZE, FAIL, "can't adjust metadata accumulator") +@@ -485,7 +489,8 @@ H5F__accum_write(H5F_shared_t *f_sh, H5FD_mem_t map_type, haddr_t addr, size_t s + accum->size += size; + } /* end if */ + /* Check if the piece of metadata being written overlaps the metadata accumulator */ +- else if (H5F_addr_overlap(addr, size, accum->loc, accum->size)) { ++ else if (H5F_LOC_VALID(accum->loc) && ++ H5F_addr_overlap(addr, size, accum->loc, accum->size)) { + size_t add_size; /* New size of the accumulator buffer */ + + /* Check if the new metadata is entirely within the current accumulator */ +@@ -745,7 +750,8 @@ H5F__accum_write(H5F_shared_t *f_sh, H5FD_mem_t map_type, haddr_t addr, size_t s + /* (Note that this could be improved by updating the accumulator + * with [some of] the information just read in. -QAK) + */ +- if (H5F_addr_overlap(addr, size, accum->loc, accum->size)) { ++ if (H5F_LOC_VALID(accum->loc) && ++ H5F_addr_overlap(addr, size, accum->loc, accum->size)) { + /* Check for write starting before beginning of accumulator */ + if (H5F_addr_le(addr, accum->loc)) { + /* Check for write ending within accumulator */ +@@ -868,6 +874,7 @@ H5F__accum_free(H5F_shared_t *f_sh, H5FD_mem_t H5_ATTR_UNUSED type, haddr_t addr + + /* Adjust the metadata accumulator to remove the freed block, if it overlaps */ + if ((f_sh->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) && ++ H5F_LOC_VALID(accum->loc) && + H5F_addr_overlap(addr, size, accum->loc, accum->size)) { + size_t overlap_size; /* Size of overlap with accumulator */ + diff --git a/When-evicting-driver-info-block-NULL-the-corresponding-entry.patch b/When-evicting-driver-info-block-NULL-the-corresponding-entry.patch new file mode 100644 index 0000000..d9f85a7 --- /dev/null +++ b/When-evicting-driver-info-block-NULL-the-corresponding-entry.patch @@ -0,0 +1,31 @@ +From: Egbert Eich +Date: Thu Sep 29 13:47:30 2022 +0200 +Subject: When evicting driver info block, NULL the corresponding entry +Patch-mainline: Not yet +Git-repo: ssh://eich@192.168.122.1:/home/eich/sources/HPC/hdf5 +Git-commit: 6d5496f17ed5aa65cbb0498e0bf70b0d599dc336 +References: + +This prevents it from another attempt to unpin it in H5F__dest() which may +happen due to malformed hdf5 files which leads to a segfault. + +This fixes CVE-2021-46242 + +Signed-off-by: Egbert Eich +Signed-off-by: Egbert Eich +--- + src/H5Fsuper.c | 2 ++ + 1 file changed, 2 insertions(+) +diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c +index 60b045ae29..1283790c57 100644 +--- a/src/H5Fsuper.c ++++ b/src/H5Fsuper.c +@@ -1044,6 +1044,8 @@ done: + /* Evict the driver info block from the cache */ + if (sblock && H5AC_expunge_entry(f, H5AC_DRVRINFO, sblock->driver_addr, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTEXPUNGE, FAIL, "unable to expunge driver info block") ++ ++ f->shared->drvinfo = NULL; + } /* end if */ + + /* Unpin & discard superblock */ diff --git a/hdf5.changes b/hdf5.changes index 1464aa2..35516c8 100644 --- a/hdf5.changes +++ b/hdf5.changes @@ -1,3 +1,32 @@ +------------------------------------------------------------------- +Sat Oct 15 13:29:22 UTC 2022 - Egbert Eich + +- Fix CVEs: + * CVE-2021-46244 (bsc#1195215) + Compound-datatypes-may-not-have-members-of-size-0.patch + * CVE-2018-13867 (bsc#1101906) + Validate-location-offset-of-the-accumulated-metadata-when-comparing.patch + * CVE-2018-16438 (bsc#1107069) + Make-sure-info-block-for-external-links-has-at-least-3-bytes.patch + * CVE-2020-10812 (bsc#1167400) + Hot-fix-for-CVE-2020-10812.patch + * CVE-2021-45830 (bsc#1194375) + H5O_fsinfo_decode-Make-more-resilient-to-out-of-bounds-read.patch + * CVE-2019-8396 (bsc#1125882) + H5O__pline_decode-Make-more-resilient-to-out-of-bounds-read.patch + * CVE-2018-11205 (bsc#1093663) + Pass-compact-chunk-size-info-to-ensure-requested-elements-are-within-bounds.patch + * CVE-2021-46242 (bsc#1195212) + When-evicting-driver-info-block-NULL-the-corresponding-entry.patch + * CVE-2021-45833 (bsc#1194366) + Report-error-if-dimensions-of-chunked-storage-in-data-layout-2.patch + * CVE-2018-14031 (bsc#1101475) + H5O_dtype_decode_helper-Parent-of-enum-needs-to-have-same-size-as-enum-itself.patch + * CVE-2018-17439 (bsc#1111598) + H5IMget_image_info-H5Sget_simple_extent_dims-does-not-exceed-array-size.patch +- Fix an error message: + Fix-error-message-not-the-name-but-the-link-information-is-parsed.patch + ------------------------------------------------------------------- Wed Sep 21 01:09:47 UTC 2022 - Stefan BrĂ¼ns diff --git a/hdf5.spec b/hdf5.spec index 67966e4..6b00432 100644 --- a/hdf5.spec +++ b/hdf5.spec @@ -438,6 +438,18 @@ Patch7: hdf5-mpi.patch Patch8: Disable-phdf5-tests.patch # Imported from Fedora, strip flags from h5cc wrapper Patch10: hdf5-wrappers.patch +Patch101: H5O_fsinfo_decode-Make-more-resilient-to-out-of-bounds-read.patch +Patch102: H5O__pline_decode-Make-more-resilient-to-out-of-bounds-read.patch +Patch103: H5O_dtype_decode_helper-Parent-of-enum-needs-to-have-same-size-as-enum-itself.patch +Patch104: Report-error-if-dimensions-of-chunked-storage-in-data-layout-2.patch +Patch105: When-evicting-driver-info-block-NULL-the-corresponding-entry.patch +Patch106: Pass-compact-chunk-size-info-to-ensure-requested-elements-are-within-bounds.patch +Patch107: Validate-location-offset-of-the-accumulated-metadata-when-comparing.patch +Patch108: Make-sure-info-block-for-external-links-has-at-least-3-bytes.patch +Patch109: Hot-fix-for-CVE-2020-10812.patch +Patch110: Compound-datatypes-may-not-have-members-of-size-0.patch +Patch111: H5IMget_image_info-H5Sget_simple_extent_dims-does-not-exceed-array-size.patch + BuildRequires: fdupes %if 0%{?use_sz2} BuildRequires: libsz2-devel @@ -679,6 +691,17 @@ library packages. # %%patch7 -p1 %patch8 -p1 %patch10 -p1 +%patch101 -p1 +%patch102 -p1 +%patch103 -p1 +%patch104 -p1 +%patch105 -p1 +%patch106 -p1 +%patch107 -p1 +%patch108 -p1 +%patch109 -p1 +%patch110 -p1 +%patch111 -p1 %if %{without hpc} # baselibs looks different for different flavors - generate it on the fly From bbdc8538d43deda3a39808a418bc9c591272249f31bd2a26c24a19226e9aa998 Mon Sep 17 00:00:00 2001 From: Dmitry Roshchin Date: Tue, 15 Nov 2022 17:24:36 +0000 Subject: [PATCH 2/2] Accepting request 1035734 from home:badshah400:branches:science Add to specfile missing patch: Fix-error-message-not-the-name-but-the-link-information-is-parsed.patch OBS-URL: https://build.opensuse.org/request/show/1035734 OBS-URL: https://build.opensuse.org/package/show/science/hdf5?expand=0&rev=160 --- hdf5.changes | 6 ++++++ hdf5.spec | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/hdf5.changes b/hdf5.changes index 35516c8..c1dacb7 100644 --- a/hdf5.changes +++ b/hdf5.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Tue Nov 15 04:52:12 UTC 2022 - Atri Bhattacharya + +- Add to specfile missing patch: + Fix-error-message-not-the-name-but-the-link-information-is-parsed.patch + ------------------------------------------------------------------- Sat Oct 15 13:29:22 UTC 2022 - Egbert Eich diff --git a/hdf5.spec b/hdf5.spec index 6b00432..849fb1a 100644 --- a/hdf5.spec +++ b/hdf5.spec @@ -1,5 +1,5 @@ # -# spec file +# spec file for package hdf5 # # Copyright (c) 2022 SUSE LLC # @@ -436,6 +436,7 @@ Patch6: hdf5-Remove-timestamps-from-binaries.patch # Could be ported but it's unknown if it's still needed Patch7: hdf5-mpi.patch Patch8: Disable-phdf5-tests.patch +Patch9: Fix-error-message-not-the-name-but-the-link-information-is-parsed.patch # Imported from Fedora, strip flags from h5cc wrapper Patch10: hdf5-wrappers.patch Patch101: H5O_fsinfo_decode-Make-more-resilient-to-out-of-bounds-read.patch @@ -690,6 +691,7 @@ library packages. %patch6 -p1 # %%patch7 -p1 %patch8 -p1 +%patch9 -p1 %patch10 -p1 %patch101 -p1 %patch102 -p1