summaryrefslogtreecommitdiffstats
path: root/src/H5Sselect.c
diff options
context:
space:
mode:
authormattjala <124107509+mattjala@users.noreply.github.com>2023-05-16 17:54:55 (GMT)
committerGitHub <noreply@github.com>2023-05-16 17:54:55 (GMT)
commit196078958c0c48f63aa8202e9447f3c75c98c26a (patch)
treea89a00c90eed0ac070afcd4db99586b50c98c545 /src/H5Sselect.c
parentf49a728a08ddc6f9915fd846aed1bc5f28978e64 (diff)
downloadhdf5-196078958c0c48f63aa8202e9447f3c75c98c26a.zip
hdf5-196078958c0c48f63aa8202e9447f3c75c98c26a.tar.gz
hdf5-196078958c0c48f63aa8202e9447f3c75c98c26a.tar.bz2
Prevent buffer overrun in H5S_select_deserialize (#2953)
Diffstat (limited to 'src/H5Sselect.c')
-rw-r--r--src/H5Sselect.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/src/H5Sselect.c b/src/H5Sselect.c
index 02889f7..28c30ea 100644
--- a/src/H5Sselect.c
+++ b/src/H5Sselect.c
@@ -521,11 +521,12 @@ H5S_select_valid(const H5S_t *space)
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S_select_deserialize(H5S_t **space, const uint8_t **p)
+H5S_select_deserialize(H5S_t **space, const uint8_t **p, const size_t p_size)
{
- uint32_t sel_type; /* Pointer to the selection type */
- herr_t ret_value = FAIL; /* Return value */
-
+ uint32_t sel_type; /* Pointer to the selection type */
+ herr_t ret_value = FAIL; /* Return value */
+ const uint8_t *p_end = *p + p_size - 1; /* Pointer to last valid byte in buffer */
+ hbool_t skip = (p_size == SIZE_MAX ? TRUE : FALSE); /* If p_size is unknown, skip buffer checks */
FUNC_ENTER_NOAPI(FAIL)
HDassert(space);
@@ -533,24 +534,26 @@ H5S_select_deserialize(H5S_t **space, const uint8_t **p)
/* Selection-type specific coding is moved to the callbacks. */
/* Decode selection type */
+ if (H5_IS_KNOWN_BUFFER_OVERFLOW(skip, *p, sizeof(uint32_t), p_end))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_OVERFLOW, FAIL, "buffer overflow while decoding selection type")
UINT32DECODE(*p, sel_type);
/* Make routine for selection type */
switch (sel_type) {
case H5S_SEL_POINTS: /* Sequence of points selected */
- ret_value = (*H5S_sel_point->deserialize)(space, p);
+ ret_value = (*H5S_sel_point->deserialize)(space, p, p_size - sizeof(uint32_t), skip);
break;
case H5S_SEL_HYPERSLABS: /* Hyperslab selection defined */
- ret_value = (*H5S_sel_hyper->deserialize)(space, p);
+ ret_value = (*H5S_sel_hyper->deserialize)(space, p, p_size - sizeof(uint32_t), skip);
break;
case H5S_SEL_ALL: /* Entire extent selected */
- ret_value = (*H5S_sel_all->deserialize)(space, p);
+ ret_value = (*H5S_sel_all->deserialize)(space, p, p_size - sizeof(uint32_t), skip);
break;
case H5S_SEL_NONE: /* Nothing selected */
- ret_value = (*H5S_sel_none->deserialize)(space, p);
+ ret_value = (*H5S_sel_none->deserialize)(space, p, p_size - sizeof(uint32_t), skip);
break;
default: