Index: LibRaw-0.15.4/src/libraw_cxx.cpp
===================================================================
--- LibRaw-0.15.4.orig/src/libraw_cxx.cpp	2020-07-07 16:34:00.953592308 +0200
+++ LibRaw-0.15.4/src/libraw_cxx.cpp	2020-07-07 16:49:09.306993054 +0200
@@ -1752,6 +1752,20 @@ libraw_processed_image_t * LibRaw::dcraw
             return NULL;
         }
 
+    if (T.tlength < 64u)
+        {
+            if (errcode)
+                *errcode = EINVAL;
+            return NULL;
+        }
+
+    if (INT64(T.tlength) > 1024ULL * 1024ULL * LIBRAW_MAX_THUMBNAIL_MB)
+        {
+            if (errcode)
+                *errcode = LIBRAW_DATA_ERROR;
+            return NULL;
+        }
+
     if (T.tformat == LIBRAW_THUMBNAIL_BITMAP)
         {
             libraw_processed_image_t * ret = 
@@ -1994,8 +2008,22 @@ int LibRaw::dcraw_ppm_tiff_writer(const
     }
 }
 
+#define THUMB_READ_BEYOND  16384
 void LibRaw::kodak_thumb_loader()
 {
+    INT64 est_datasize = T.theight * T.twidth / 3; // is 0.3 bytes per pixel good estimate?
+    if (ID.toffset < 0)
+            throw LIBRAW_EXCEPTION_IO_CORRUPT;
+
+    if (ID.toffset + est_datasize > ID.input->size() + THUMB_READ_BEYOND)
+            throw LIBRAW_EXCEPTION_IO_EOF;
+
+    if (INT64(T.theight) * INT64(T.twidth) > 1024ULL * 1024ULL * LIBRAW_MAX_THUMBNAIL_MB)
+            throw LIBRAW_EXCEPTION_IO_CORRUPT;
+
+    if (INT64(T.theight) * INT64(T.twidth) < 64ULL)
+            throw LIBRAW_EXCEPTION_IO_CORRUPT;
+
     // some kodak cameras
     ushort s_height = S.height, s_width = S.width,s_iwidth = S.iwidth,s_iheight=S.iheight;
     int s_colors = P1.colors;
@@ -2169,6 +2197,25 @@ int LibRaw::unpack_thumb(void)
     CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY);
     CHECK_ORDER_BIT(LIBRAW_PROGRESS_THUMB_LOAD);
 
+#define THUMB_SIZE_CHECKT(A) \
+  do { \
+    if (INT64(A) > 1024ULL * 1024ULL * LIBRAW_MAX_THUMBNAIL_MB) throw LIBRAW_EXCEPTION_IO_CORRUPT; \
+    if (INT64(A) > 0 &&  INT64(A) < 64ULL)        throw LIBRAW_EXCEPTION_IO_CORRUPT; \
+  } while (0)
+
+#define THUMB_SIZE_CHECKTNZ(A) \
+  do { \
+    if (INT64(A) > 1024ULL * 1024ULL * LIBRAW_MAX_THUMBNAIL_MB) throw LIBRAW_EXCEPTION_IO_CORRUPT; \
+    if (INT64(A) < 64ULL)        throw LIBRAW_EXCEPTION_IO_CORRUPT; \
+  } while (0)
+
+
+#define THUMB_SIZE_CHECKWH(W,H) \
+  do { \
+    if (INT64(W)*INT64(H) > 1024ULL * 1024ULL * LIBRAW_MAX_THUMBNAIL_MB) throw LIBRAW_EXCEPTION_IO_CORRUPT; \
+    if (INT64(W)*INT64(H) < 64ULL)        throw LIBRAW_EXCEPTION_IO_CORRUPT; \
+  } while (0)
+
     try {
 		if(!libraw_internal_data.internal_data.input)
 			return LIBRAW_INPUT_CLOSED;
@@ -2189,6 +2236,7 @@ int LibRaw::unpack_thumb(void)
                 ID.input->seek(ID.toffset, SEEK_SET);
                 if ( write_thumb == &LibRaw::jpeg_thumb)
                     {
+                        THUMB_SIZE_CHECKTNZ(T.tlength);
                         if(T.thumb) free(T.thumb);
                         T.thumb = (char *) malloc (T.tlength);
                         merror (T.thumb, "jpeg_thumb()");
@@ -2200,7 +2248,9 @@ int LibRaw::unpack_thumb(void)
                     }
                 else if (write_thumb == &LibRaw::ppm_thumb)
                     {
+                        THUMB_SIZE_CHECKWH(T.twidth, T.theight);
                         T.tlength = T.twidth * T.theight*3;
+                        THUMB_SIZE_CHECKTNZ(T.tlength);
                         if(T.thumb) free(T.thumb);
 
                         T.thumb = (char *) malloc (T.tlength);
@@ -2216,6 +2266,7 @@ int LibRaw::unpack_thumb(void)
                 else if (write_thumb == &LibRaw::ppm16_thumb)
                     {
                         T.tlength = T.twidth * T.theight*3;
+                        THUMB_SIZE_CHECKTNZ(T.tlength);
                         ushort *t_thumb = (ushort*)calloc(T.tlength,2);
                         ID.input->read(t_thumb,2,T.tlength);
                         if ((libraw_internal_data.unpacker_data.order= 0x4949) == (ntohs(0x1234) == 0x1234))
Index: LibRaw-0.15.4/libraw/libraw_const.h
===================================================================
--- LibRaw-0.15.4.orig/libraw/libraw_const.h	2020-07-07 16:34:00.985592497 +0200
+++ LibRaw-0.15.4/libraw/libraw_const.h	2020-07-07 16:34:43.765846849 +0200
@@ -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 thumbnail size, default is 512Mb*/
+#ifndef LIBRAW_MAX_THUMBNAIL_MB
+#define LIBRAW_MAX_THUMBNAIL_MB 512L
+#endif
+
 enum LibRaw_decoder_flags
 {
     LIBRAW_DECODER_LEGACY = 1,      
