diff options
author | Binh-Minh Ribler <bmribler@hdfgroup.org> | 2019-01-04 17:46:29 (GMT) |
---|---|---|
committer | Binh-Minh Ribler <bmribler@hdfgroup.org> | 2019-01-04 17:46:29 (GMT) |
commit | f891c38c6e724e9032a534512618b9650be76377 (patch) | |
tree | 9738f44c0b6c826dd20638114c6c089fc94e49b1 | |
parent | 74a3710a996fca5ed7fcb4dd8919a7a8521de1de (diff) | |
download | hdf5-f891c38c6e724e9032a534512618b9650be76377.zip hdf5-f891c38c6e724e9032a534512618b9650be76377.tar.gz hdf5-f891c38c6e724e9032a534512618b9650be76377.tar.bz2 |
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)
-rw-r--r-- | release_docs/RELEASE.txt | 22 | ||||
-rw-r--r-- | src/H5Dchunk.c | 30 | ||||
-rw-r--r-- | 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<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) 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 |