[Bf-blender-cvs] [7c864388fc0] blender-v2.92-release: Fix T71960: Malformed .bmp files lead to crash

Sergey Sharybin noreply at git.blender.org
Mon Feb 15 11:21:27 CET 2021


Commit: 7c864388fc0de1e92b8ad9394966d38ffea17daf
Author: Sergey Sharybin
Date:   Mon Feb 8 12:26:50 2021 +0100
Branches: blender-v2.92-release
https://developer.blender.org/rB7c864388fc0de1e92b8ad9394966d38ffea17daf

Fix T71960: Malformed .bmp files lead to crash

Add a boundary check, avoiding access past actual data.

Ideally would need to report error to the user somehow,
but it doesn't seem to be easy to do.

This is a minimal safe patch. The proper complete fix is
being worked on by Jesse.

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

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

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

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

diff --git a/source/blender/imbuf/intern/bmp.c b/source/blender/imbuf/intern/bmp.c
index 58ce02f28ae..a5c558fc216 100644
--- a/source/blender/imbuf/intern/bmp.c
+++ b/source/blender/imbuf/intern/bmp.c
@@ -111,6 +111,14 @@ bool imb_is_a_bmp(const uchar *buf, size_t size)
   return checkbmp(buf, size);
 }
 
+static size_t imb_bmp_calc_row_size_in_bytes(size_t x, size_t depth)
+{
+  if (depth <= 8) {
+    return (depth * x + 31) / 32 * 4;
+  }
+  return (depth >> 3) * x;
+}
+
 ImBuf *imb_bmp_decode(const uchar *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
 {
   ImBuf *ibuf = NULL;
@@ -130,7 +138,8 @@ ImBuf *imb_bmp_decode(const uchar *mem, size_t size, int flags, char colorspace[
 
   colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
 
-  bmp = mem + LITTLE_LONG(*(int *)(mem + 10));
+  const size_t pixel_data_offset = LITTLE_LONG(*(int *)(mem + 10));
+  bmp = mem + pixel_data_offset;
 
   if (CHECK_HEADER_FIELD_BMP(mem)) {
     /* skip fileheader */
@@ -150,6 +159,13 @@ ImBuf *imb_bmp_decode(const uchar *mem, size_t size, int flags, char colorspace[
   xppm = LITTLE_LONG(bmi.biXPelsPerMeter);
   yppm = LITTLE_LONG(bmi.biYPelsPerMeter);
 
+  const size_t row_size_in_bytes = imb_bmp_calc_row_size_in_bytes(x, depth);
+  const size_t num_expected_data_bytes = row_size_in_bytes * y;
+  const size_t num_actual_data_bytes = size - pixel_data_offset;
+  if (num_actual_data_bytes < num_expected_data_bytes) {
+    return NULL;
+  }
+
   if (depth <= 8) {
     ibuf_depth = 24;
   }
@@ -179,7 +195,6 @@ ImBuf *imb_bmp_decode(const uchar *mem, size_t size, int flags, char colorspace[
     rect = (uchar *)ibuf->rect;
 
     if (depth <= 8) {
-      const int rowsize = (depth * x + 31) / 32 * 4;
       const char(*palette)[4] = (void *)(mem + skip);
       const int startmask = ((1 << depth) - 1) << 8;
       for (size_t i = y; i > 0; i--) {
@@ -212,7 +227,7 @@ ImBuf *imb_bmp_decode(const uchar *mem, size_t size, int flags, char colorspace[
           }
         }
         /* Advance to the next row */
-        bmp += (rowsize - nbytes);
+        bmp += (row_size_in_bytes - nbytes);
       }
     }
     else if (depth == 16) {



More information about the Bf-blender-cvs mailing list