File H5O_fsinfo_decode-Make-more-resilient-to-out-of-bounds-read.patch of Package hdf5.28370

From: Egbert Eich <eich@suse.com>
Date: Wed Oct 5 07:17:24 2022 +0200
Subject: H5O_fsinfo_decode() Make more resilient to out-of-bounds read
Patch-mainline: Not yet
Git-repo: https://github.com/HDFGroup/hdf5
Git-commit: 46763e3c6111a0eb20e9198a99f4dbbfa6845af5
References: 

Malformed hdf5 files may have trunkated content which does not match
the expected size. This function attempts to decode these it will read
past the end of the allocated space which may lead to a crash. Make sure
each element is within bounds before reading.

This fixes CVE-2021-45830.

Signed-off-by: Egbert Eich <eich@suse.com>
Additions
Signed-off-by: Egbert Eich <eich@suse.de>
---
 src/H5Ofsinfo.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/src/H5Ofsinfo.c b/src/H5Ofsinfo.c
index 5628350d72..f50077470b 100644
--- a/src/H5Ofsinfo.c
+++ b/src/H5Ofsinfo.c
@@ -78,6 +78,13 @@ H5FL_DEFINE_STATIC(H5O_fsinfo_t);
  *
  *-------------------------------------------------------------------------
  */
+static char err[] = "ran off end of input buffer while decoding";
+#define VERIFY_LIMIT(p,s,l)					  \
+  if (p + s - 1 > l) {                                            \
+    HCOMMON_ERROR(H5E_RESOURCE, H5E_NOSPACE, err);                \
+    HGOTO_DONE(NULL)                                              \
+  }
+
 static void *
 H5O_fsinfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags,
                   unsigned H5_ATTR_UNUSED *ioflags, size_t p_size, const uint8_t *p)
@@ -102,6 +109,7 @@ H5O_fsinfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUS
         fsinfo->fs_addr[ptype - 1] = HADDR_UNDEF;
 
     /* Version of message */
+    VERIFY_LIMIT(p,1,p_end)
     vers = *p++;
 
     if (vers == H5O_FSINFO_VERSION_0) {
@@ -115,6 +123,7 @@ H5O_fsinfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUS
         fsinfo->pgend_meta_thres    = H5F_FILE_SPACE_PGEND_META_THRES;
         fsinfo->eoa_pre_fsm_fsalloc = HADDR_UNDEF;
 
+        VERIFY_LIMIT(p, 1 + H5F_SIZEOF_SIZE(f), p_end);
         strategy = (H5F_file_space_type_t)*p++; /* File space strategy */
         H5F_DECODE_LENGTH(f, p, threshold);     /* Free-space section threshold */
 
@@ -160,6 +169,7 @@ H5O_fsinfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUS
         HDassert(vers >= H5O_FSINFO_VERSION_1);
 
         fsinfo->version  = vers;
+        VERIFY_LIMIT(p, 1 + 1 + 2 * H5F_SIZEOF_SIZE(f) + 2 + H5F_SIZEOF_ADDR(f), p_end);
         fsinfo->strategy = (H5F_fspace_strategy_t)*p++; /* File space strategy */
         fsinfo->persist  = *p++;                        /* Free-space persist or not */
         H5F_DECODE_LENGTH(f, p, fsinfo->threshold);     /* Free-space section threshold */
@@ -171,9 +181,11 @@ H5O_fsinfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUS
 
         /* Decode addresses of free space managers, if persisting */
         if (fsinfo->persist)
-            for (ptype = H5F_MEM_PAGE_SUPER; ptype < H5F_MEM_PAGE_NTYPES; ptype++)
+	     for (ptype = H5F_MEM_PAGE_SUPER; ptype < H5F_MEM_PAGE_NTYPES; ptype++) {
+                VERIFY_LIMIT(p, H5F_SIZEOF_SIZE(f), p_end);
                 H5F_addr_decode(f, &p, &(fsinfo->fs_addr[ptype - 1]));
 
+            }
         fsinfo->mapped = FALSE;
     }
 
openSUSE Build Service is sponsored by