[Bf-blender-cvs] [77616082f44] master: Fix T89542: Crash when loading certain .hdr files

Jesse Yurkovich noreply at git.blender.org
Wed Jan 12 05:58:15 CET 2022


Commit: 77616082f44da5258faf9ec0d53618c721b88c62
Author: Jesse Yurkovich
Date:   Tue Jan 11 20:48:32 2022 -0800
Branches: master
https://developer.blender.org/rB77616082f44da5258faf9ec0d53618c721b88c62

Fix T89542: Crash when loading certain .hdr files

The direct cause of the bug in question was passing in the raw memory
buffer to sscanf. It should be called with a null-terminated buffer;
which isn't guaranteed when blindly trusting the file data.

When attempting to fuzz this code path, a variety of other crashes were
discovered and fixed.

Differential Revision: https://developer.blender.org/D11952

===================================================================

M	source/blender/imbuf/intern/radiance_hdr.c

===================================================================

diff --git a/source/blender/imbuf/intern/radiance_hdr.c b/source/blender/imbuf/intern/radiance_hdr.c
index 7f4e4dd31df..0bca68b93bc 100644
--- a/source/blender/imbuf/intern/radiance_hdr.c
+++ b/source/blender/imbuf/intern/radiance_hdr.c
@@ -77,7 +77,7 @@ static const unsigned char *oldreadcolrs(RGBE *scan,
     scan[0][BLU] = *mem++;
     scan[0][EXP] = *mem++;
     if (scan[0][RED] == 1 && scan[0][GRN] == 1 && scan[0][BLU] == 1) {
-      for (i = scan[0][EXP] << rshift; i > 0; i--) {
+      for (i = scan[0][EXP] << rshift; i > 0 && len > 0; i--) {
         COPY_RGBE(scan[-1], scan[0]);
         scan++;
         len--;
@@ -227,7 +227,7 @@ struct ImBuf *imb_loadhdr(const unsigned char *mem,
   int found = 0;
   int width = 0, height = 0;
   const unsigned char *ptr, *mem_eof = mem + size;
-  char oriY[80], oriX[80];
+  char oriY[3], oriX[3];
 
   if (!imb_is_a_hdr(mem, size)) {
     return NULL;
@@ -244,13 +244,19 @@ struct ImBuf *imb_loadhdr(const unsigned char *mem,
     }
   }
 
-  if ((found && (x < (size + 2))) == 0) {
+  if ((found && (x < (size - 1))) == 0) {
     /* Data not found! */
     return NULL;
   }
 
-  if (sscanf((const char *)&mem[x + 1],
-             "%79s %d %79s %d",
+  x++;
+
+  /* sscanf requires a null-terminated buffer argument */
+  char buf[32] = {0};
+  memcpy(buf, &mem[x], MIN2(sizeof(buf) - 1, size - x));
+
+  if (sscanf(buf,
+             "%2s %d %2s %d",
              (char *)&oriY,
              &height,
              (char *)&oriX,
@@ -258,8 +264,18 @@ struct ImBuf *imb_loadhdr(const unsigned char *mem,
     return NULL;
   }
 
+  if (width < 1 || height < 1) {
+    return NULL;
+  }
+
+  /* Checking that width x height does not extend past mem_eof is not easily possible
+   * since the format uses RLE compression. Can cause excessive memory allocation to occur. */
+
   /* find end of this line, data right behind it */
-  ptr = (const unsigned char *)strchr((const char *)&mem[x + 1], '\n');
+  ptr = (const unsigned char *)strchr((const char *)&mem[x], '\n');
+  if (ptr == NULL || ptr >= mem_eof) {
+    return NULL;
+  }
   ptr++;
 
   if (flags & IB_test) {



More information about the Bf-blender-cvs mailing list