From fa4f48d1e46c0dbef9422f794da998915a3b7615 Mon Sep 17 00:00:00 2001 From: bmribler <39579120+bmribler@users.noreply.github.com> Date: Wed, 1 May 2024 08:42:22 -0400 Subject: [PATCH] Fix heap-buffer-overflow in H5Fio.c (#4450) The buffer size for checksum was smaller than H5_SIZEOF_CHKSUM, causing an overflow while calculating the offset to the checksum in the buffer. A check was added so H5F_get_checksums would fail appropriately in all of its occurrences. Fix gh-4434 --- src/H5B2cache.c | 18 ++++++++++++------ src/H5EAcache.c | 30 ++++++++++++++++++++---------- src/H5FAcache.c | 18 ++++++++++++------ src/H5FScache.c | 12 ++++++++---- src/H5Fio.c | 11 +++++++++-- src/H5Fsuper_cache.c | 6 ++++-- src/H5HFcache.c | 12 ++++++++---- src/H5Ocache.c | 12 ++++++++---- src/H5SMcache.c | 12 ++++++++---- 9 files changed, 89 insertions(+), 42 deletions(-) diff --git a/src/H5B2cache.c b/src/H5B2cache.c index 8ff0a45d370..c78b54c33f5 100644 --- a/src/H5B2cache.c +++ b/src/H5B2cache.c @@ -194,17 +194,19 @@ H5B2__cache_hdr_verify_chksum(const void *_image, size_t len, void H5_ATTR_UNUSE uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; /* Return value */ - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5B2__cache_hdr_verify_chksum() */ @@ -557,7 +559,7 @@ H5B2__cache_int_verify_chksum(const void *_image, size_t H5_ATTR_UNUSED len, voi uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; /* Return value */ - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); @@ -568,11 +570,13 @@ H5B2__cache_int_verify_chksum(const void *_image, size_t H5_ATTR_UNUSED len, voi ((size_t)(udata->nrec + 1) * H5B2_INT_POINTER_SIZE(udata->hdr, udata->depth)); /* Get stored and computed checksums */ - H5F_get_checksums(image, chk_size, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, chk_size, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5B2__cache_int_verify_chksum() */ @@ -956,7 +960,7 @@ H5B2__cache_leaf_verify_chksum(const void *_image, size_t H5_ATTR_UNUSED len, vo uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; /* Return value */ - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); @@ -966,11 +970,13 @@ H5B2__cache_leaf_verify_chksum(const void *_image, size_t H5_ATTR_UNUSED len, vo chk_size = H5B2_LEAF_PREFIX_SIZE + (udata->nrec * udata->hdr->rrec_size); /* Get stored and computed checksums */ - H5F_get_checksums(image, chk_size, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, chk_size, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5B2__cache_leaf_verify_chksum() */ diff --git a/src/H5EAcache.c b/src/H5EAcache.c index 74a3abe2189..951c40dccc1 100644 --- a/src/H5EAcache.c +++ b/src/H5EAcache.c @@ -249,17 +249,19 @@ H5EA__cache_hdr_verify_chksum(const void *_image, size_t len, void H5_ATTR_UNUSE uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_EARRAY, H5E_CANTDECODE, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5EA__cache_hdr_verify_chksum() */ @@ -639,17 +641,19 @@ H5EA__cache_iblock_verify_chksum(const void *_image, size_t len, void H5_ATTR_UN uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_EARRAY, H5E_CANTDECODE, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5EA__cache_iblock_verify_chksum() */ @@ -1039,17 +1043,19 @@ H5EA__cache_sblock_verify_chksum(const void *_image, size_t len, void H5_ATTR_UN uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_EARRAY, H5E_CANTDECODE, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5EA__cache_sblock_verify_chksum() */ @@ -1445,17 +1451,19 @@ H5EA__cache_dblock_verify_chksum(const void *_image, size_t len, void H5_ATTR_UN uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_EARRAY, H5E_CANTDECODE, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5EA__cache_sblock_verify_chksum() */ @@ -1866,17 +1874,19 @@ H5EA__cache_dblk_page_verify_chksum(const void *_image, size_t len, void H5_ATTR uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_EARRAY, H5E_CANTDECODE, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5EA__cache_dblk_page_verify_chksum() */ diff --git a/src/H5FAcache.c b/src/H5FAcache.c index 2920dd1aaeb..ecc25e216a2 100644 --- a/src/H5FAcache.c +++ b/src/H5FAcache.c @@ -195,17 +195,19 @@ H5FA__cache_hdr_verify_chksum(const void *_image, size_t len, void H5_ATTR_UNUSE uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_FARRAY, H5E_CANTGET, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FA__cache_hdr_verify_chksum() */ @@ -578,17 +580,19 @@ H5FA__cache_dblock_verify_chksum(const void *_image, size_t len, void H5_ATTR_UN uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_FARRAY, H5E_CANTGET, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FA__cache_dblock_verify_chksum() */ @@ -980,17 +984,19 @@ H5FA__cache_dblk_page_verify_chksum(const void *_image, size_t len, void H5_ATTR uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_FARRAY, H5E_CANTGET, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FA__cache_dblk_page_verify_chksum() */ diff --git a/src/H5FScache.c b/src/H5FScache.c index 3fa31f00042..7f8edf69f13 100644 --- a/src/H5FScache.c +++ b/src/H5FScache.c @@ -184,17 +184,19 @@ H5FS__cache_hdr_verify_chksum(const void *_image, size_t len, void H5_ATTR_UNUSE uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; /* Return value */ - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FS__cache_hdr_verify_chksum() */ @@ -887,17 +889,19 @@ H5FS__cache_sinfo_verify_chksum(const void *_image, size_t len, void H5_ATTR_UNU uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; /* Return value */ - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FS__cache_sinfo_verify_chksum() */ diff --git a/src/H5Fio.c b/src/H5Fio.c index b0c24010e86..2cd8a53ba53 100644 --- a/src/H5Fio.c +++ b/src/H5Fio.c @@ -498,12 +498,18 @@ H5F__evict_cache_entries(H5F_t *f) herr_t H5F_get_checksums(const uint8_t *buf, size_t buf_size, uint32_t *s_chksum /*out*/, uint32_t *c_chksum /*out*/) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT /* Check arguments */ assert(buf); assert(buf_size); + /* Check for buffer size smaller than H5_SIZEOF_CHKSUM */ + if (buf_size < H5_SIZEOF_CHKSUM) + HGOTO_ERROR(H5E_IO, H5E_BADVALUE, FAIL, "checksum buffer is smaller than expected"); + /* Return the stored checksum */ if (s_chksum) { const uint8_t *chk_p; /* Pointer into raw data buffer */ @@ -519,5 +525,6 @@ H5F_get_checksums(const uint8_t *buf, size_t buf_size, uint32_t *s_chksum /*out* if (c_chksum) *c_chksum = H5_checksum_metadata(buf, buf_size - H5_SIZEOF_CHKSUM, 0); - FUNC_LEAVE_NOAPI(SUCCEED) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_get_chksums() */ diff --git a/src/H5Fsuper_cache.c b/src/H5Fsuper_cache.c index 7161b8b2fd3..9c475ab26a2 100644 --- a/src/H5Fsuper_cache.c +++ b/src/H5Fsuper_cache.c @@ -371,7 +371,7 @@ H5F__cache_superblock_verify_chksum(const void *_image, size_t len, void *_udata uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE assert(image); assert(udata); @@ -380,12 +380,14 @@ H5F__cache_superblock_verify_chksum(const void *_image, size_t len, void *_udata if (udata->super_vers >= HDF5_SUPERBLOCK_VERSION_2) { /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; } +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5F__cache_superblock_verify_chksum() */ diff --git a/src/H5HFcache.c b/src/H5HFcache.c index 823e2dea28e..db55bf0b4d0 100644 --- a/src/H5HFcache.c +++ b/src/H5HFcache.c @@ -412,17 +412,19 @@ H5HF__cache_hdr_verify_chksum(const void *_image, size_t len, void H5_ATTR_UNUSE uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; /* Return value */ - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF__cache_hdr_verify_chksum() */ @@ -867,17 +869,19 @@ H5HF__cache_iblock_verify_chksum(const void *_image, size_t len, void H5_ATTR_UN uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; /* Return value */ - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF__cache_iblock_verify_chksum() */ diff --git a/src/H5Ocache.c b/src/H5Ocache.c index cc8033baf55..87f321cb986 100644 --- a/src/H5Ocache.c +++ b/src/H5Ocache.c @@ -220,7 +220,7 @@ H5O__cache_verify_chksum(const void *_image, size_t len, void *_udata) H5O_cache_ud_t *udata = (H5O_cache_ud_t *)_udata; /* User data for callback */ htri_t ret_value = true; - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE assert(image); assert(udata); @@ -231,7 +231,8 @@ H5O__cache_verify_chksum(const void *_image, size_t len, void *_udata) uint32_t computed_chksum; /* Computed metadata checksum value */ /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; @@ -239,6 +240,7 @@ H5O__cache_verify_chksum(const void *_image, size_t len, void *_udata) else assert(!(udata->common.file_intent & H5F_ACC_SWMR_WRITE)); +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5O__cache_verify_chksum() */ @@ -624,7 +626,7 @@ H5O__cache_chk_verify_chksum(const void *_image, size_t len, void *_udata) H5O_chk_cache_ud_t *udata = (H5O_chk_cache_ud_t *)_udata; /* User data for callback */ htri_t ret_value = true; - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE assert(image); @@ -634,12 +636,14 @@ H5O__cache_chk_verify_chksum(const void *_image, size_t len, void *_udata) uint32_t computed_chksum; /* Computed metadata checksum value */ /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; } +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5O__cache_chk_verify_chksum() */ diff --git a/src/H5SMcache.c b/src/H5SMcache.c index 77f1eef222e..7bf0575ed45 100644 --- a/src/H5SMcache.c +++ b/src/H5SMcache.c @@ -156,17 +156,19 @@ H5SM__cache_table_verify_chksum(const void *_image, size_t len, void H5_ATTR_UNU uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; /* Return value */ - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, len, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5SM__cache_table_verify_chksum() */ @@ -480,7 +482,7 @@ H5SM__cache_list_verify_chksum(const void *_image, size_t H5_ATTR_UNUSED len, vo uint32_t computed_chksum; /* Computed metadata checksum value */ htri_t ret_value = true; /* Return value */ - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments */ assert(image); @@ -490,11 +492,13 @@ H5SM__cache_list_verify_chksum(const void *_image, size_t H5_ATTR_UNUSED len, vo chk_size = H5SM_LIST_SIZE(udata->f, udata->header->num_messages); /* Get stored and computed checksums */ - H5F_get_checksums(image, chk_size, &stored_chksum, &computed_chksum); + if (H5F_get_checksums(image, chk_size, &stored_chksum, &computed_chksum) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "can't get checksums"); if (stored_chksum != computed_chksum) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5SM__cache_list_verify_chksum() */