summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBinh-Minh Ribler <bmribler@hdfgroup.org>2019-01-04 17:46:29 (GMT)
committerBinh-Minh Ribler <bmribler@hdfgroup.org>2019-01-04 17:46:29 (GMT)
commitf891c38c6e724e9032a534512618b9650be76377 (patch)
tree9738f44c0b6c826dd20638114c6c089fc94e49b1
parent74a3710a996fca5ed7fcb4dd8919a7a8521de1de (diff)
downloadhdf5-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.txt22
-rw-r--r--src/H5Dchunk.c30
-rw-r--r--test/chunk_info.c8
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