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.18.2/dcraw/dcraw.c
===================================================================
--- libraw-0.18.2.orig/dcraw/dcraw.c	2018-03-30 08:23:23.446758445 -0400
+++ libraw-0.18.2/dcraw/dcraw.c	2018-03-30 08:23:23.442758415 -0400
@@ -16761,7 +16761,11 @@ bw:   colors = 1;
 #else
 	tiff_bps > 16
 #endif
-      || tiff_samples > 4 || colors > 4 || colors < 1)
+      || 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.18.2/internal/dcraw_common.cpp
===================================================================
--- libraw-0.18.2.orig/internal/dcraw_common.cpp	2018-03-30 08:23:23.446758445 -0400
+++ libraw-0.18.2/internal/dcraw_common.cpp	2018-03-30 08:23:23.442758415 -0400
@@ -15414,7 +15414,11 @@ bw:   colors = 1;
 #else
 	tiff_bps > 16
 #endif
-      || tiff_samples > 4 || colors > 4 || colors < 1)
+      || 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.18.2/libraw/libraw_const.h
===================================================================
--- libraw-0.18.2.orig/libraw/libraw_const.h	2018-03-30 08:23:23.446758445 -0400
+++ libraw-0.18.2/libraw/libraw_const.h	2018-03-30 08:23:23.442758415 -0400
@@ -20,6 +20,11 @@ it under the terms of the one of two lic
 #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_whitebalance_code
 {
 /*
Index: libraw-0.18.2/src/libraw_cxx.cpp
===================================================================
--- libraw-0.18.2.orig/src/libraw_cxx.cpp	2018-03-30 08:23:23.446758445 -0400
+++ libraw-0.18.2/src/libraw_cxx.cpp	2018-03-30 08:23:23.442758415 -0400
@@ -2436,7 +2436,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;
@@ -2493,6 +2494,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)
@@ -2508,6 +2513,9 @@ int LibRaw::unpack(void)
 				S.raw_pitch = (decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY_WITH_MARGINS) ? S.raw_width*8 : 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));
 			if(!(decoder_info.decoder_flags &  LIBRAW_DECODER_ADOBECOPYPIXEL))
 			{
