From f891c38c6e724e9032a534512618b9650be76377 Mon Sep 17 00:00:00 2001 From: Binh-Minh Ribler Date: Fri, 4 Jan 2019 11:46:29 -0600 Subject: Fixed CVE division-by-zero issues Description: Fixed HDFFV-10577 and similar issues found in H5Dchunk.c. All the occurrences are in: H5D__create_chunk_map_single H5D__create_chunk_file_map_hyper H5D__chunk_allocate H5D__chunk_update_old_edge_chunks H5D__chunk_prune_by_extent H5D__chunk_copy_cb H5D__chunk_collective_fill Also updated RELEASE.txt for the chunk query functions and removed some blank lines in chunk_info.c. Platforms tested: Linux/64 (jelly) Linux/64 (platypus) Darwin (osx1010test) --- release_docs/RELEASE.txt | 22 +++++++++++++++++++--- src/H5Dchunk.c | 30 ++++++++++++++++++++++++++---- test/chunk_info.c | 8 ++++---- 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 59f1944..185cd96 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -75,8 +75,6 @@ New Features (ADB - 2018/09/26, HDFFV-10594) - - - Incorrectly installed private header files were removed from CMake installs. @@ -110,6 +108,16 @@ New Features Library: -------- + - Added new chunk query functions + + The following public functions are added to discover information about + the chunks in an HDF5 file. + herr_t H5Dget_num_chunks(dset_id, fspace_id, *nchunks) + herr_t H5Dget_chunk_info_by_coord(dset_id, *coord, *filter_mask, *addr, *size) + herr_t H5Dget_chunk_info(dset_id, fspace_id, index, *coord, *filter_mask, *addr, *size) + + (BMR - 2018/11/07, HDFFV-10615) + - Allow pre-generated H5Tinit.c and H5make_libsettings.c to be used. Rather than always running H5detect and generating H5Tinit.c and @@ -117,7 +125,6 @@ New Features (ADB - 2018/09/18, HDFFV-10332) - - Several empty public header files where removed from the distribution The following files were empty placeholders. They are for internal @@ -236,6 +243,15 @@ Bug Fixes since HDF5-1.10.3 release (JTH - 2018/08/25, HDFFV-10501) + - There was an incorrect protection against division by zero reported + to The HDF Group as issue #CVE-2018-17233. + + Protection against division by zero were added in several internal + functions. + + (BMR - 2018/02/26, HDFFV-10577) + + Java Library: ---------------- - JNI native library dependencies diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index 3722475..ccde498 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -1507,6 +1507,9 @@ H5D__create_chunk_map_single(H5D_chunk_map_t *fm, const H5D_io_info_t /* Set chunk location & hyperslab size */ for(u = 0; u < fm->f_ndims; u++) { + /* Validate this chunk dimension */ + if(fm->layout->u.chunk.dim[u] == 0) + HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "chunk size must be > 0, dim = %u ", u) HDassert(sel_start[u] == sel_end[u]); chunk_info->scaled[u] = sel_start[u] / fm->layout->u.chunk.dim[u]; coords[u] = chunk_info->scaled[u] * fm->layout->u.chunk.dim[u]; @@ -1593,6 +1596,9 @@ H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t /* Set initial chunk location & hyperslab size */ for(u = 0; u < fm->f_ndims; u++) { + /* Validate this chunk dimension */ + if(fm->layout->u.chunk.dim[u] == 0) + HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "chunk size must be > 0, dim = %u ", u) scaled[u] = start_scaled[u] = sel_start[u] / fm->layout->u.chunk.dim[u]; coords[u] = start_coords[u] = scaled[u] * fm->layout->u.chunk.dim[u]; end[u] = (coords[u] + fm->chunk_dim[u]) - 1; @@ -4059,6 +4065,9 @@ H5D__chunk_allocate(const H5D_io_info_t *io_info, hbool_t full_overwrite, hsize_ * assume here that all elements of space_dim are > 0. This is checked at * the top of this function. */ for(op_dim=0; op_dim 0, dim = %u ", op_dim) min_unalloc[op_dim] = (old_dim[op_dim] + chunk_dim[op_dim] - 1) / chunk_dim[op_dim]; max_unalloc[op_dim] = (space_dim[op_dim] - 1) / chunk_dim[op_dim]; @@ -4502,13 +4511,17 @@ H5D__chunk_update_old_edge_chunks(H5D_t *dset, hsize_t old_dim[]) /* Start off with this dimension marked as not needing to be modified */ new_full_dim[op_dim] = FALSE; + /* Validate this chunk dimension */ + if(chunk_dim[op_dim] == 0) + HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "chunk size must be > 0, dim = %u ", op_dim) + /* Calculate offset of first previously incomplete chunk in this * dimension */ - old_edge_chunk_sc[op_dim] = (old_dim[op_dim] / chunk_dim[op_dim]); + old_edge_chunk_sc[op_dim] = (old_dim[op_dim] / chunk_dim[op_dim]); /* Calculate the largest offset of chunks that might need to be * modified in this dimension */ - max_edge_chunk_sc[op_dim] = MIN((old_dim[op_dim] - 1) / chunk_dim[op_dim], + max_edge_chunk_sc[op_dim] = MIN((old_dim[op_dim] - 1) / chunk_dim[op_dim], MAX((space_dim[op_dim] / chunk_dim[op_dim]), 1) - 1); /* Check for old_dim aligned with chunk boundary in this dimension, if @@ -4519,7 +4532,7 @@ H5D__chunk_update_old_edge_chunks(H5D_t *dset, hsize_t old_dim[]) /* Check if the dataspace expanded enough to cause the old edge chunks * in this dimension to become full */ - if((space_dim[op_dim]/chunk_dim[op_dim]) >= (old_edge_chunk_sc[op_dim] + 1)) + if((space_dim[op_dim]/chunk_dim[op_dim]) >= (old_edge_chunk_sc[op_dim] + 1)) new_full_dim[op_dim] = TRUE; } /* end for */ @@ -4644,6 +4657,8 @@ H5D__chunk_collective_fill(const H5D_t *dset, H5D_chunk_coll_info_t *chunk_info, HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "Can't retrieve MPI size") /* Distribute evenly the number of blocks between processes. */ + if(mpi_size == 0) + HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "Resulted in division by zero") num_blocks = chunk_info->num_io / mpi_size; /* value should be the same on all procs */ /* after evenly distributing the blocks between processes, are @@ -5084,6 +5099,10 @@ H5D__chunk_prune_by_extent(H5D_t *dset, const hsize_t *old_dim) HDmemset(min_mod_chunk_sc, 0, sizeof(min_mod_chunk_sc)); HDmemset(max_mod_chunk_sc, 0, sizeof(max_mod_chunk_sc)); for(op_dim = 0; op_dim < (unsigned)space_ndims; op_dim++) { + /* Validate this chunk dimension */ + if(chunk_dim[op_dim] == 0) + HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "chunk size must be > 0, dim = %u ", op_dim) + /* Calculate the largest offset of chunks that might need to be * modified in this dimension */ max_mod_chunk_sc[op_dim] = (old_dim[op_dim] - 1) / chunk_dim[op_dim]; @@ -5739,9 +5758,12 @@ H5D__chunk_copy_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata) /* (background buffer has already been zeroed out, if not expanding) */ if(udata->cpy_info->expand_ref) { size_t ref_count; + size_t dt_size; /* Determine # of reference elements to copy */ - ref_count = nbytes / H5T_get_size(udata->dt_src); + if((dt_size = H5T_get_size(udata->dt_src)) == 0) + HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "size must not be 0") + ref_count = nbytes / dt_size; /* Copy the reference elements */ if(H5O_copy_expand_ref(udata->file_src, buf, udata->idx_info_dst->f, bkg, ref_count, H5T_get_ref_type(udata->dt_src), udata->cpy_info) < 0) diff --git a/test/chunk_info.c b/test/chunk_info.c index f5a6fdc..866fd68 100644 --- a/test/chunk_info.c +++ b/test/chunk_info.c @@ -1484,19 +1484,19 @@ test_get_chunk_info_110(hid_t fapl) /* Set version bounds for creating file */ if(H5Pset_libver_bounds(fapl, low, high) < 0) TEST_ERROR - + /* Test getting chunk info when Single Chunk index type is used */ if(test_chunk_info_single_chunk(filename, fapl) < 0) TEST_ERROR - + /* Test getting chunk info when Implicit index type is used */ if(test_chunk_info_implicit(filename, fapl) < 0) TEST_ERROR - + /* Test getting chunk info when Fixed Array index type is used */ if(test_chunk_info_fixed_array(filename, fapl) < 0) TEST_ERROR - + /* Test getting chunk info when Extensible Array index type is used */ if(test_chunk_info_extensible_array(filename, fapl) < 0) TEST_ERROR -- cgit v0.12 From 82dd54c26b11245c36f65a044e9b717dc2c337e0 Mon Sep 17 00:00:00 2001 From: Binh-Minh Ribler Date: Fri, 4 Jan 2019 16:05:11 -0600 Subject: Revised text --- release_docs/RELEASE.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 92c2414..addd9b0 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -119,7 +119,7 @@ New Features -------- - Added new chunk query functions - The following public functions are added to discover information about + The following public functions were added to discover information about the chunks in an HDF5 file. herr_t H5Dget_num_chunks(dset_id, fspace_id, *nchunks) herr_t H5Dget_chunk_info_by_coord(dset_id, *coord, *filter_mask, *addr, *size) @@ -261,8 +261,9 @@ Bug Fixes since HDF5-1.10.3 release - There was an incorrect protection against division by zero reported to The HDF Group as issue #CVE-2018-17233. - Protection against division by zero were added in several internal - functions. + Protection against division by zero was added to address the issue + #CVE-2018-17233. In addition, several similar occurrences in the same + file were fixed as well. (BMR - 2018/02/26, HDFFV-10577) -- cgit v0.12