CVE-2017-6886: Improper Restriction of Operations within the Bounds of a Memory Buffer (CWE-119)
value: An error within the "parse_tiff_ifd()" function (internal/dcraw_common.cpp) in LibRaw versions before 0.18.2 can be exploited to corrupt memory.
CWE description: The product performs operations on a memory buffer, but it reads from or writes to a memory location outside the buffer's intended boundary. This may result in read or write operations on unexpected memory locations that could be linked to other variables, data structures, or internal program data.
CVSS v3 base score: 9.8
Published: 2017-05-16T16:29Z
Repository: https://github.com/LibRaw/LibRaw
Language: C++
Files changed: dcraw/dcraw.c, internal/dcraw_common.cpp
Commit date: 2017-03-04 21:27:39 +0300
Commit message: Secunia SA75000 advisory: several buffer overruns

Diff: diff --git a/dcraw/dcraw.c b/dcraw/dcraw.c
index b6fc378a..4c44a2a0 100644
--- a/dcraw/dcraw.c
+++ b/dcraw/dcraw.c
@@ -12868,10 +12868,14 @@ int CLASS parse_tiff_ifd(int base)
       if (!strcmp(model, "DSLR-A100") && tiff_ifd[ifd].t_width == 3872)
       {
         load_raw = &CLASS sony_arw_load_raw;
         data_offset = get4() + base;
         ifd++;
+#ifdef LIBRAW_LIBRARY_BUILD
+	if (ifd >= sizeof tiff_ifd / sizeof tiff_ifd[0])
+	  throw LIBRAW_EXCEPTION_IO_CORRUPT;
+#endif    
         break;
       }
 #ifdef LIBRAW_LIBRARY_BUILD
       if (!strncmp(make, "Hasselblad", 10) && libraw_internal_data.unpacker_data.hasselblad_parser_flag)
       {
@@ -13175,11 +13179,11 @@ int CLASS parse_tiff_ifd(int base)
       }
       maximum = 0xffff;
       break;
     case 50454: /* Sinar tag */
     case 50455:
-      if (len > 2560000 || !(cbuf = (char *)malloc(len)))
+      if (len < 1 || len > 2560000 || !(cbuf = (char *)malloc(len)))
         break;
 #ifndef LIBRAW_LIBRARY_BUILD
       fread(cbuf, 1, len, ifp);
 #else
       if (fread(cbuf, 1, len, ifp) != len)
@@ -14793,11 +14797,15 @@ int CLASS parse_jpeg(int offset)
       raw_height = get2();
       raw_width = get2();
     }
     order = get2();
     hlen = get4();
-    if (get4() == 0x48454150) /* "HEAP" */
+    if (get4() == 0x48454150
+#ifdef LIBRAW_LIBRARY_BUILD
+	&& (save+hlen) >= 0 && (save+hlen)<=ifp->size()
+#endif
+	) /* "HEAP" */
     {
 #ifdef LIBRAW_LIBRARY_BUILD
       imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
       imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
 #endif
diff --git a/internal/dcraw_common.cpp b/internal/dcraw_common.cpp
index 44802e04..8edf5359 100644
--- a/internal/dcraw_common.cpp
+++ b/internal/dcraw_common.cpp
@@ -11540,10 +11540,14 @@ int CLASS parse_tiff_ifd(int base)
       if (!strcmp(model, "DSLR-A100") && tiff_ifd[ifd].t_width == 3872)
       {
         load_raw = &CLASS sony_arw_load_raw;
         data_offset = get4() + base;
         ifd++;
+#ifdef LIBRAW_LIBRARY_BUILD
+	if (ifd >= sizeof tiff_ifd / sizeof tiff_ifd[0])
+	  throw LIBRAW_EXCEPTION_IO_CORRUPT;
+#endif    
         break;
       }
 #ifdef LIBRAW_LIBRARY_BUILD
       if (!strncmp(make, "Hasselblad", 10) && libraw_internal_data.unpacker_data.hasselblad_parser_flag)
       {
@@ -11847,11 +11851,11 @@ int CLASS parse_tiff_ifd(int base)
       }
       maximum = 0xffff;
       break;
     case 50454: /* Sinar tag */
     case 50455:
-      if (len > 2560000 || !(cbuf = (char *)malloc(len)))
+      if (len < 1 || len > 2560000 || !(cbuf = (char *)malloc(len)))
         break;
 #ifndef LIBRAW_LIBRARY_BUILD
       fread(cbuf, 1, len, ifp);
 #else
       if (fread(cbuf, 1, len, ifp) != len)
@@ -13465,11 +13469,15 @@ int CLASS parse_jpeg(int offset)
       raw_height = get2();
       raw_width = get2();
     }
     order = get2();
     hlen = get4();
-    if (get4() == 0x48454150) /* "HEAP" */
+    if (get4() == 0x48454150
+#ifdef LIBRAW_LIBRARY_BUILD
+	&& (save+hlen) >= 0 && (save+hlen)<=ifp->size()
+#endif
+	) /* "HEAP" */
     {
 #ifdef LIBRAW_LIBRARY_BUILD
       imgdata.lens.makernotes.CameraMount = LIBRAW_MOUNT_FixedLens;
       imgdata.lens.makernotes.LensMount = LIBRAW_MOUNT_FixedLens;
 #endif

Vulnerable code:       if (len > 2560000 || !(cbuf = (char *)malloc(len)))
    if (get4() == 0x48454150) /* "HEAP" */
      if (len > 2560000 || !(cbuf = (char *)malloc(len)))
    if (get4() == 0x48454150) /* "HEAP" */
Fixed code: #ifdef LIBRAW_LIBRARY_BUILD
	if (ifd >= sizeof tiff_ifd / sizeof tiff_ifd[0])
	  throw LIBRAW_EXCEPTION_IO_CORRUPT;
#endif    
      if (len < 1 || len > 2560000 || !(cbuf = (char *)malloc(len)))
    if (get4() == 0x48454150
#ifdef LIBRAW_LIBRARY_BUILD
	&& (save+hlen) >= 0 && (save+hlen)<=ifp->size()
#endif
	) /* "HEAP" */
#ifdef LIBRAW_LIBRARY_BUILD
	if (ifd >= sizeof tiff_ifd / sizeof tiff_ifd[0])
	  throw LIBRAW_EXCEPTION_IO_CORRUPT;
#endif    
      if (len < 1 || len > 2560000 || !(cbuf = (char *)malloc(len)))
    if (get4() == 0x48454150
#ifdef LIBRAW_LIBRARY_BUILD
	&& (save+hlen) >= 0 && (save+hlen)<=ifp->size()
#endif
	) /* "HEAP" */