From f891c38c6e724e9032a534512618b9650be76377 Mon Sep 17 00:00:00 2001
From: Binh-Minh Ribler <bmribler@hdfgroup.org>
Date: Fri, 4 Jan 2019 11:46:29 -0600
Subject: [PATCH] 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)

---
 src/H5Dchunk.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c
index 021335f..1dc7a25 100644
--- a/src/H5Dchunk.c
+++ b/src/H5Dchunk.c
@@ -1380,6 +1380,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->coords[u] = (sel_start[u] / fm->layout->u.chunk.dim[u]) * fm->layout->u.chunk.dim[u];
     } /* end for */
@@ -1465,6 +1468,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)
         start_coords[u] = (sel_start[u] / fm->layout->u.chunk.dim[u]) * fm->layout->u.chunk.dim[u];
         coords[u] = start_coords[u];
         end[u] = (coords[u] + fm->chunk_dim[u]) - 1;
@@ -3595,6 +3601,9 @@ H5D__chunk_allocate(const H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite,
      * that we 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]) * chunk_dim[op_dim];
         max_unalloc[op_dim] = ((space_dim[op_dim] - 1) / chunk_dim[op_dim])
@@ -3865,6 +3874,8 @@ H5D__chunk_collective_fill(const H5D_t *dset, hid_t dxpl_id,
         HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy property list")
 
     /* 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
@@ -4324,6 +4335,10 @@ H5D__chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dim)
     HDmemset(min_mod_chunk_off, 0, sizeof(min_mod_chunk_off));
     HDmemset(max_mod_chunk_off, 0, sizeof(max_mod_chunk_off));
     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)
+
         /* Calculate the largest offset of chunks that might need to be
          * modified in this dimension */
         max_mod_chunk_off[op_dim] = chunk_dim[op_dim] * ((old_dim[op_dim] - 1)
@@ -4929,9 +4944,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->dxpl_id, udata->idx_info_dst->f, bkg, ref_count, H5T_get_ref_type(udata->dt_src), udata->cpy_info) < 0)
-- 
2.23.0

