summaryrefslogtreecommitdiffstats
path: root/src/H5Olayout.c
diff options
context:
space:
mode:
authormattjala <124107509+mattjala@users.noreply.github.com>2023-05-12 20:22:55 (GMT)
committerGitHub <noreply@github.com>2023-05-12 20:22:55 (GMT)
commit364145f144cb68a5635ad9f7dad0e4210e3d513a (patch)
tree5a5a7b4f2a343c8e96bc486abbbbe4d94fb0b094 /src/H5Olayout.c
parent0d4a12d7cd0f0c10b385533365fc1f3ebeef8e74 (diff)
downloadhdf5-364145f144cb68a5635ad9f7dad0e4210e3d513a.zip
hdf5-364145f144cb68a5635ad9f7dad0e4210e3d513a.tar.gz
hdf5-364145f144cb68a5635ad9f7dad0e4210e3d513a.tar.bz2
Prevent buffer overrun in H5S_select_deserialize (#2931)
* Prevent buffer overrun in H5S_select_deserialize The call to H5S_select_deserialize from H5S_decode doesn't have the buffer size available to it, so to allow decoding there I set it to assume a max size buffer for now. Making the buffer size known in H5S_decode could be done by modifying the external API's H5Sdecode, or splitting H5Sdecode into two functions using a macro (similar to H5Sencode), with the macro taking one argument and assuming a max buffer size. * Conditional buffer check in H5S_select_deserialize Moved and renamed a macro for only checking buffer overflow when buffer size is known from H5Odtype.c to H5private.h, so it can be used throughout the library. Also silenced some build warnings about types.
Diffstat (limited to 'src/H5Olayout.c')
-rw-r--r--src/H5Olayout.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/src/H5Olayout.c b/src/H5Olayout.c
index f784f24..645ad73 100644
--- a/src/H5Olayout.c
+++ b/src/H5Olayout.c
@@ -634,13 +634,27 @@ H5O__layout_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU
heap_block_p += tmp_size;
/* Source selection */
- if (H5S_SELECT_DESERIALIZE(&mesg->storage.u.virt.list[i].source_select,
- &heap_block_p) < 0)
+ avail_buffer_space = heap_block_p_end - heap_block_p + 1;
+
+ if (avail_buffer_space <= 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_OVERFLOW, NULL,
+ "buffer overflow while decoding layout")
+
+ if (H5S_SELECT_DESERIALIZE(&mesg->storage.u.virt.list[i].source_select, &heap_block_p,
+ (size_t)(avail_buffer_space)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "can't decode source space selection")
/* Virtual selection */
+
+ /* Buffer space must be updated after previous deserialization */
+ avail_buffer_space = heap_block_p_end - heap_block_p + 1;
+
+ if (avail_buffer_space <= 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_OVERFLOW, NULL,
+ "buffer overflow while decoding layout")
+
if (H5S_SELECT_DESERIALIZE(&mesg->storage.u.virt.list[i].source_dset.virtual_select,
- &heap_block_p) < 0)
+ &heap_block_p, (size_t)(avail_buffer_space)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL,
"can't decode virtual space selection")