Blame SOURCES/LibRaw-CVE-2020-15503.patch

1d1a77
diff -urNp LibRaw-0.19.5.orig/libraw/libraw_const.h LibRaw-0.19.5/libraw/libraw_const.h
1d1a77
--- LibRaw-0.19.5.orig/libraw/libraw_const.h	2020-08-10 18:32:18.669459968 +0200
1d1a77
+++ LibRaw-0.19.5/libraw/libraw_const.h	2020-08-10 18:48:10.462282067 +0200
1d1a77
@@ -24,6 +24,12 @@ it under the terms of the one of two lic
1d1a77
 #define LIBRAW_MAX_ALLOC_MB 2048L
1d1a77
 #endif
1d1a77
 
1d1a77
+/* limit thumbnail size, default is 512Mb*/
1d1a77
+#ifndef LIBRAW_MAX_THUMBNAIL_MB
1d1a77
+#define LIBRAW_MAX_THUMBNAIL_MB 512L
1d1a77
+#endif
1d1a77
+
1d1a77
+
1d1a77
 /* Change to non-zero to allow (broken) CRW (and other) files metadata 
1d1a77
    loop prevention */
1d1a77
 #ifndef LIBRAW_METADATA_LOOP_PREVENTION
1d1a77
diff -urNp LibRaw-0.19.5.orig/src/libraw_cxx.cpp LibRaw-0.19.5/src/libraw_cxx.cpp
1d1a77
--- LibRaw-0.19.5.orig/src/libraw_cxx.cpp	2020-08-10 18:32:18.672459987 +0200
1d1a77
+++ LibRaw-0.19.5/src/libraw_cxx.cpp	2020-08-10 18:49:18.616688826 +0200
1d1a77
@@ -3712,6 +3712,21 @@ libraw_processed_image_t *LibRaw::dcraw_
1d1a77
     return NULL;
1d1a77
   }
1d1a77
 
1d1a77
+  if (T.tlength < 64u)
1d1a77
+  {
1d1a77
+      if (errcode)
1d1a77
+          *errcode = EINVAL;
1d1a77
+      return NULL;
1d1a77
+  }
1d1a77
+
1d1a77
+  if (INT64(T.tlength) > 1024ULL * 1024ULL * LIBRAW_MAX_THUMBNAIL_MB)
1d1a77
+  {
1d1a77
+      if (errcode)
1d1a77
+          *errcode = LIBRAW_TOO_BIG;
1d1a77
+      return NULL;
1d1a77
+  }
1d1a77
+
1d1a77
+
1d1a77
   if (T.tformat == LIBRAW_THUMBNAIL_BITMAP)
1d1a77
   {
1d1a77
     libraw_processed_image_t *ret = (libraw_processed_image_t *)::malloc(sizeof(libraw_processed_image_t) + T.tlength);
1d1a77
@@ -3976,6 +3991,12 @@ void LibRaw::kodak_thumb_loader()
1d1a77
   if (ID.toffset + est_datasize > ID.input->size() + THUMB_READ_BEYOND)
1d1a77
     throw LIBRAW_EXCEPTION_IO_EOF;
1d1a77
 
1d1a77
+  if(INT64(T.theight) * INT64(T.twidth) > 1024ULL * 1024ULL * LIBRAW_MAX_THUMBNAIL_MB)
1d1a77
+      throw LIBRAW_EXCEPTION_IO_CORRUPT;
1d1a77
+
1d1a77
+  if (INT64(T.theight) * INT64(T.twidth) < 64ULL)
1d1a77
+      throw LIBRAW_EXCEPTION_IO_CORRUPT;
1d1a77
+
1d1a77
   // some kodak cameras
1d1a77
   ushort s_height = S.height, s_width = S.width, s_iwidth = S.iwidth, s_iheight = S.iheight;
1d1a77
   ushort s_flags = libraw_internal_data.unpacker_data.load_flags;
1d1a77
@@ -4237,6 +4258,25 @@ int LibRaw::unpack_thumb(void)
1d1a77
   CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY);
1d1a77
   CHECK_ORDER_BIT(LIBRAW_PROGRESS_THUMB_LOAD);
1d1a77
 
1d1a77
+#define THUMB_SIZE_CHECKT(A) \
1d1a77
+  do { \
1d1a77
+    if (INT64(A) > 1024ULL * 1024ULL * LIBRAW_MAX_THUMBNAIL_MB) throw LIBRAW_EXCEPTION_IO_CORRUPT; \
1d1a77
+    if (INT64(A) > 0 &&  INT64(A) < 64ULL)        throw LIBRAW_EXCEPTION_IO_CORRUPT; \
1d1a77
+  } while (0)
1d1a77
+
1d1a77
+#define THUMB_SIZE_CHECKTNZ(A) \
1d1a77
+  do { \
1d1a77
+    if (INT64(A) > 1024ULL * 1024ULL * LIBRAW_MAX_THUMBNAIL_MB) throw LIBRAW_EXCEPTION_IO_CORRUPT; \
1d1a77
+    if (INT64(A) < 64ULL)        throw LIBRAW_EXCEPTION_IO_CORRUPT; \
1d1a77
+  } while (0)
1d1a77
+
1d1a77
+
1d1a77
+#define THUMB_SIZE_CHECKWH(W,H) \
1d1a77
+  do { \
1d1a77
+    if (INT64(W)*INT64(H) > 1024ULL * 1024ULL * LIBRAW_MAX_THUMBNAIL_MB) throw LIBRAW_EXCEPTION_IO_CORRUPT; \
1d1a77
+    if (INT64(W)*INT64(H) < 64ULL)        throw LIBRAW_EXCEPTION_IO_CORRUPT; \
1d1a77
+  } while (0)
1d1a77
+
1d1a77
   try
1d1a77
   {
1d1a77
     if (!libraw_internal_data.internal_data.input)
1d1a77
@@ -4267,6 +4307,7 @@ int LibRaw::unpack_thumb(void)
1d1a77
 
1d1a77
         if (INT64(ID.toffset) + tsize > ID.input->size() + THUMB_READ_BEYOND)
1d1a77
           throw LIBRAW_EXCEPTION_IO_EOF;
1d1a77
+        THUMB_SIZE_CHECKT(tsize);
1d1a77
       }
1d1a77
       else
1d1a77
       {
1d1a77
@@ -4280,6 +4321,7 @@ int LibRaw::unpack_thumb(void)
1d1a77
       ID.input->seek(ID.toffset, SEEK_SET);
1d1a77
       if (write_thumb == &LibRaw::jpeg_thumb)
1d1a77
       {
1d1a77
+        THUMB_SIZE_CHECKTNZ(T.tlength);
1d1a77
         if (T.thumb)
1d1a77
           free(T.thumb);
1d1a77
         T.thumb = (char *)malloc(T.tlength);
1d1a77
@@ -4326,6 +4368,7 @@ int LibRaw::unpack_thumb(void)
1d1a77
       {
1d1a77
         if (t_bytesps > 1)
1d1a77
           throw LIBRAW_EXCEPTION_IO_CORRUPT; // 8-bit thumb, but parsed for more bits
1d1a77
+        THUMB_SIZE_CHECKWH(T.twidth, T.theight);
1d1a77
         int t_length = T.twidth * T.theight * t_colors;
1d1a77
 
1d1a77
         if (T.tlength && T.tlength < t_length) // try to find tiff ifd with needed offset
1d1a77
@@ -4351,8 +4394,12 @@ int LibRaw::unpack_thumb(void)
1d1a77
                 T.tcolors = 1;
1d1a77
             }
1d1a77
             T.tlength = total_size;
1d1a77
+            THUMB_SIZE_CHECKTNZ(T.tlength);
1d1a77
             if (T.thumb)
1d1a77
               free(T.thumb);
1d1a77
+            
1d1a77
+            THUMB_SIZE_CHECKTNZ(T.tlength);
1d1a77
+            
1d1a77
             T.thumb = (char *)malloc(T.tlength);
1d1a77
             merror(T.thumb, "ppm_thumb()");
1d1a77
 
1d1a77
@@ -4400,10 +4447,15 @@ int LibRaw::unpack_thumb(void)
1d1a77
         if (t_bytesps > 2)
1d1a77
           throw LIBRAW_EXCEPTION_IO_CORRUPT; // 16-bit thumb, but parsed for more bits
1d1a77
         int o_bps = (imgdata.params.raw_processing_options & LIBRAW_PROCESSING_USE_PPM16_THUMBS) ? 2 : 1;
1d1a77
+        THUMB_SIZE_CHECKWH(T.twidth, T.theight);
1d1a77
         int o_length = T.twidth * T.theight * t_colors * o_bps;
1d1a77
         int i_length = T.twidth * T.theight * t_colors * 2;
1d1a77
         if (!T.tlength)
1d1a77
           T.tlength = o_length;
1d1a77
+        THUMB_SIZE_CHECKTNZ(o_length);
1d1a77
+        THUMB_SIZE_CHECKTNZ(i_length);
1d1a77
+        THUMB_SIZE_CHECKTNZ(T.tlength);
1d1a77
+
1d1a77
         ushort *t_thumb = (ushort *)calloc(i_length, 1);
1d1a77
         ID.input->read(t_thumb, 1, i_length);
1d1a77
         if ((libraw_internal_data.unpacker_data.order == 0x4949) == (ntohs(0x1234) == 0x1234))