Backport of:

From 1668953e67ce7b75527316cd2df141406e47c803 Mon Sep 17 00:00:00 2001
From: Alex Tutubalin <lexa@lexa.ru>
Date: Mon, 29 Jan 2018 09:22:06 +0300
Subject: [PATCH] additional image/alloc size checks

---
 Changelog.txt                    |  6 ++++++
 dcraw/dcraw.c                    |  8 ++++++--
 internal/dcraw_common.cpp        |  8 ++++++--
 internal/libraw_internal_funcs.h |  2 +-
 libraw/libraw_const.h            |  5 +++++
 src/libraw_cxx.cpp               | 10 +++++++++-
 6 files changed, 33 insertions(+), 6 deletions(-)

#diff --git a/Changelog.txt b/Changelog.txt
#index c9fc5209..067bc15e 100755
#--- a/Changelog.txt
#+++ b/Changelog.txt
#@@ -1,3 +1,9 @@
#+2018-01-29  Alex Tutubalin <lexa@lexa.ru>
#+ * Checks for width+left_margin/height+top_margin not larger than 64k
#+ * LIBRAW_MAX_ALLOC_MB define limits maximum image/raw_image allocation
#+   (default is 2048 so 2Gb per array)
#+ * LibRaw::read_shorts item count is now unsigned
#+
# 2018-01-19  Alex Tutubalin <lexa@lexa.ru>
# Secunia #79000: 
# Credit: Laurent Delosieres, Secunia Research at Flexera
Index: libraw-0.17.1/dcraw/dcraw.c
===================================================================
--- libraw-0.17.1.orig/dcraw/dcraw.c	2018-03-30 09:19:54.611643901 -0400
+++ libraw-0.17.1/dcraw/dcraw.c	2018-03-30 09:22:07.591867607 -0400
@@ -14654,7 +14654,11 @@ bw:   colors = 1;
   }
   /* Early reject for damaged images */
   if (!load_raw || height < 22 || width < 22 ||
-	tiff_bps > 16 || tiff_samples > 4 || colors > 4 || colors < 1)
+	tiff_bps > 16 || tiff_samples > 4 || colors > 4 || colors < 1
+    /* alloc in unpack() may be fooled by size adjust */
+    || ( (int)width + (int)left_margin > 65535) 
+    || ( (int)height + (int)top_margin > 65535)
+	 )
     {
       is_raw = 0;
 #ifdef LIBRAW_LIBRARY_BUILD
Index: libraw-0.17.1/internal/dcraw_common.cpp
===================================================================
--- libraw-0.17.1.orig/internal/dcraw_common.cpp	2018-03-30 09:19:54.611643901 -0400
+++ libraw-0.17.1/internal/dcraw_common.cpp	2018-03-30 09:22:33.199910557 -0400
@@ -13323,7 +13323,11 @@ bw:   colors = 1;
   }
   /* Early reject for damaged images */
   if (!load_raw || height < 22 || width < 22 ||
-	tiff_bps > 16 || tiff_samples > 4 || colors > 4 || colors < 1)
+	tiff_bps > 16 || tiff_samples > 4 || colors > 4 || colors < 1
+    /* alloc in unpack() may be fooled by size adjust */
+    || ( (int)width + (int)left_margin > 65535) 
+    || ( (int)height + (int)top_margin > 65535)
+	 )
     {
       is_raw = 0;
 #ifdef LIBRAW_LIBRARY_BUILD
Index: libraw-0.17.1/libraw/libraw_const.h
===================================================================
--- libraw-0.17.1.orig/libraw/libraw_const.h	2018-03-30 09:19:54.611643901 -0400
+++ libraw-0.17.1/libraw/libraw_const.h	2018-03-30 09:22:49.003937046 -0400
@@ -23,6 +23,11 @@ it under the terms of the one of three l
 #define LIBRAW_DEFAULT_ADJUST_MAXIMUM_THRESHOLD 0.75
 #define LIBRAW_DEFAULT_AUTO_BRIGHTNESS_THRESHOLD 0.01
 
+/* limit allocation size, default is 2Gb */
+#ifndef LIBRAW_MAX_ALLOC_MB
+#define LIBRAW_MAX_ALLOC_MB 2048L
+#endif
+
 enum LibRaw_colormatrix_type
 {
  LIBRAW_CMATRIX_NONE=0,
Index: libraw-0.17.1/src/libraw_cxx.cpp
===================================================================
--- libraw-0.17.1.orig/src/libraw_cxx.cpp	2018-03-30 09:19:54.611643901 -0400
+++ libraw-0.17.1/src/libraw_cxx.cpp	2018-03-30 09:19:54.611643901 -0400
@@ -1328,7 +1328,8 @@ int LibRaw::unpack(void)
         if(rheight < S.height + S.top_margin)
           rheight = S.height + S.top_margin;
       }
-
+    if(rwidth > 65535 || rheight > 65535) // No way to make image larger than 64k pix
+      throw LIBRAW_EXCEPTION_IO_CORRUPT;
     imgdata.rawdata.raw_image = 0;
     imgdata.rawdata.color4_image = 0;
     imgdata.rawdata.color3_image = 0;
@@ -1458,6 +1459,10 @@ int LibRaw::unpack(void)
           }
         else if(imgdata.idata.filters || P1.colors == 1) // Bayer image or single color -> decode to raw_image
           {
+
+	    if(INT64(rwidth)*INT64(rheight+8)*sizeof(imgdata.rawdata.raw_image[0]) > LIBRAW_MAX_ALLOC_MB * INT64(1024*1024))
+	      throw LIBRAW_EXCEPTION_ALLOC;
+	    
             imgdata.rawdata.raw_alloc = malloc(rwidth*(rheight+8)*sizeof(imgdata.rawdata.raw_image[0]));
             imgdata.rawdata.raw_image = (ushort*) imgdata.rawdata.raw_alloc;
             if(!S.raw_pitch)
@@ -1472,6 +1477,9 @@ int LibRaw::unpack(void)
             S.raw_pitch = S.width*8;
             // allocate image as temporary buffer, size
             imgdata.rawdata.raw_alloc = 0;
+	    if(INT64(MAX(S.width,S.raw_width))*INT64(MAX(S.height,S.raw_height))*sizeof(*imgdata.image) > LIBRAW_MAX_ALLOC_MB * INT64(1024*1024))
+	      throw LIBRAW_EXCEPTION_ALLOC;
+
             imgdata.image = (ushort (*)[4]) calloc(unsigned(MAX(S.width,S.raw_width))*unsigned(MAX(S.height,S.raw_height)),sizeof(*imgdata.image));
 	    imgdata.rawdata.raw_image = (ushort*) imgdata.image ;
 	    zero_rawimage = 1;
