From: Emilio Pozuelo Monfort <pochu@debian.org>
Date: Sat, 29 Jul 2017 11:38:28 +0200
Subject: Fix_CVE-2017-6886

--- a/dcraw/dcraw.c
+++ b/dcraw/dcraw.c
@@ -5457,7 +5457,12 @@
 	if (!strcmp(model,"DSLR-A100") && tiff_ifd[ifd].width == 3872) {
 	  load_raw = &CLASS sony_arw_load_raw;
 	  data_offset = get4()+base;
-	  ifd++;  break;
+	  ifd++;
+#ifdef LIBRAW_LIBRARY_BUILD
+	if (ifd >= sizeof tiff_ifd / sizeof tiff_ifd[0])
+	  throw LIBRAW_EXCEPTION_IO_CORRUPT;
+#endif
+	  break;
 	}
 	while (len--) {
 	  i = ftell(ifp);
@@ -5609,7 +5614,7 @@
 	break;
       case 50454:			/* Sinar tag */
       case 50455:
-	if (!(cbuf = (char *) malloc(len))) break;
+	if (len < 1 || len > 2560000 || !(cbuf = (char *) malloc(len))) break;
 	fread (cbuf, 1, len, ifp);
 	for (cp = cbuf-1; cp && cp < cbuf+len; cp = strchr(cp,'\n'))
 	  if (!strncmp (++cp,"Neutral ",8))
@@ -6338,7 +6343,19 @@
     }
     order = get2();
     hlen  = get4();
-    if (get4() == 0x48454150)		/* "HEAP" */
+
+#ifdef LIBRAW_LIBRARY_BUILD
+    struct stat st;
+    off_t fsize = 0;
+    if(!stat(ifp->fname(),&st))
+	fsize = st.st_size;
+#endif
+
+    if (get4() == 0x48454150
+#ifdef LIBRAW_LIBRARY_BUILD
+	&& (save+hlen) >= 0 && (save+hlen)<=ifp->size()
+#endif
+	) /* "HEAP" */
       parse_ciff (save+hlen, len-hlen, 0);
     if (parse_tiff (save+6)) apply_tiff();
     fseek (ifp, save+len, SEEK_SET);
--- a/internal/dcraw_common.cpp
+++ b/internal/dcraw_common.cpp
@@ -56,6 +56,10 @@
   return FC(row,col);
 }
 
+#ifdef LIBRAW_LIBRARY_BUILD
+#include <sys/stat.h>
+#endif
+
 #ifndef __GLIBC__
 char *my_memmem (char *haystack, size_t haystacklen,
 	      char *needle, size_t needlelen)
@@ -5530,7 +5534,12 @@
 	if (!strcmp(model,"DSLR-A100") && tiff_ifd[ifd].t_width == 3872) {
 	  load_raw = &CLASS sony_arw_load_raw;
 	  data_offset = get4()+base;
-	  ifd++;  break;
+	  ifd++;
+#ifdef LIBRAW_LIBRARY_BUILD
+	if (ifd >= sizeof tiff_ifd / sizeof tiff_ifd[0])
+	  throw LIBRAW_EXCEPTION_IO_CORRUPT;
+#endif
+	  break;
 	}
         if(len > 1000) len=1000; /* 1000 SubIFDs is enough */
 	while (len--) {
@@ -5705,7 +5714,7 @@
 	break;
       case 50454:			/* Sinar tag */
       case 50455:
-	if (!(cbuf = (char *) malloc(len))) break;
+	if (len < 1 || len > 2560000 || !(cbuf = (char *) malloc(len))) break;
 	fread (cbuf, 1, len, ifp);
 	for (cp = cbuf-1; cp && cp < cbuf+len; cp = strchr(cp,'\n'))
 	  if (!strncmp (++cp,"Neutral ",8))
@@ -6512,7 +6521,19 @@
     }
     order = get2();
     hlen  = get4();
-    if (get4() == 0x48454150)		/* "HEAP" */
+
+#ifdef LIBRAW_LIBRARY_BUILD
+    struct stat st;
+    off_t fsize = 0;
+    if(!stat(ifp->fname(),&st))
+	fsize = st.st_size;
+#endif
+
+    if (get4() == 0x48454150
+#ifdef LIBRAW_LIBRARY_BUILD
+	&& (save+hlen) >= 0 && (save+hlen)<=fsize
+#endif
+	) /* "HEAP" */
       parse_ciff (save+hlen, len-hlen, 0);
     if (parse_tiff (save+6)) apply_tiff();
     fseek (ifp, save+len, SEEK_SET);
