CVE-2017-16910 (published 2018-12-07T22:29Z)

An error within the "LibRaw::xtrans_interpolate()" function (internal/dcraw_common.cpp) in LibRaw versions prior to 0.18.6 can be exploited to cause an invalid read memory access and subsequently a Denial of Service condition.

Severity: MEDIUM
CVSS v2 base score: 4.3 (AV:N/AC:M/Au:N/C:N/I:N/A:P)
CVSS v3 base score: 6.5, MEDIUM (CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H)

Weakness information:
cwe_id: CWE-125
cwe_name: Out-of-bounds Read
description: The product reads data past the end, or before the beginning, of the intended buffer.
extended_description: 
            
            
             
			 
         
         

Fix information:
repo_url: https://github.com/LibRaw/LibRaw
commit_details: repo_url: https://github.com/LibRaw/LibRaw
author: Alex Tutubalin
author_date: 2017-12-02 12:28:37+03:00
msg: Secunia 76000 #2: xtrans allhex not initialized
repository: repo_url: https://github.com/LibRaw/LibRaw
repo_name: LibRaw/LibRaw
description: LibRaw is a library for reading RAW files from digital cameras
repo_language: C++
owner: LibRaw
file_changes: filename: dcraw.c
change_type: ModificationType.MODIFY
diff: @@ -7045,6 +7045,8 @@ void CLASS xtrans_interpolate(int passes)
 #endif
 
 #ifdef LIBRAW_LIBRARY_BUILD
+  if(width < TS || height < TS)
+	  throw LIBRAW_EXCEPTION_IO_CORRUPT; // too small image
 /* Check against right pattern */
   for (row = 0; row < 6; row++)
 	  for (col = 0; col < 6; col++)
@@ -7053,6 +7055,13 @@ void CLASS xtrans_interpolate(int passes)
   if(cstat[0] < 6 || cstat[0]>10 || cstat[1]< 16
     || cstat[1]>24 || cstat[2]< 6 || cstat[2]>10 || cstat[3])
 	  throw LIBRAW_EXCEPTION_IO_CORRUPT;
+
+ // Init allhex table to unreasonable values
+ for(int i = 0; i < 3; i++)
+  for(int j = 0; j < 3; j++)
+   for(int k = 0; k < 2; k++)
+    for(int l = 0; l < 8; l++)
+     allhex[i][j][k][l]=32700;
 #endif
   cielab(0, 0);
   ndir = 4 << (passes > 1);
@@ -7063,6 +7072,7 @@ void CLASS xtrans_interpolate(int passes)
   drv = (float(*)[TS][TS])(buffer + TS * TS * (ndir * 6 + 6));
   homo = (char(*)[TS][TS])(buffer + TS * TS * (ndir * 10 + 6));
 
+  int minv=0,maxv=0,minh=0,maxh=0;
   /* Map a green hexagon around each non-green pixel and vice versa:	*/
   for (row = 0; row < 3; row++)
     for (col = 0; col < 3; col++)
@@ -7083,11 +7093,25 @@ void CLASS xtrans_interpolate(int passes)
           {
             v = orth[d] * patt[g][c * 2] + orth[d + 1] * patt[g][c * 2 + 1];
             h = orth[d + 2] * patt[g][c * 2] + orth[d + 3] * patt[g][c * 2 + 1];
+	    minv=MIN(v,minv);
+	    maxv=MAX(v,maxv);
+	    minh=MIN(v,minh);
+   	    maxh=MAX(v,maxh);
             allhex[row][col][0][c ^ (g * 2 & d)] = h + v * width;
             allhex[row][col][1][c ^ (g * 2 & d)] = h + v * TS;
           }
       }
 
+#ifdef LIBRAW_LIBRARY_BUILD
+   // Check allhex table initialization
+  for(int i = 0; i < 3; i++)
+    for(int j = 0; j < 3; j++)
+      for(int k = 0; k < 2; k++)
+        for(int l = 0; l < 8; l++)
+	  if(allhex[i][j][k][l]>maxh+maxv*width+1 || allhex[i][j][k][l]<minh+minv*width-1)
+	  throw LIBRAW_EXCEPTION_IO_CORRUPT;
+  int retrycount = 0;
+#endif
   /* Set green1 and green3 to the minimum and maximum allowed values:	*/
   for (row = 2; row < height - 2; row++)
     for (min = ~(max = 0), col = 2; col < width - 2; col++)
@@ -7118,7 +7142,13 @@ void CLASS xtrans_interpolate(int passes)
         break;
       case 2:
         if ((min = ~(max = 0)) && (col += 2) < width - 3 && row > 2)
-          row--;
+	{
+           row--;
+#ifdef LIBRAW_LIBRARY_BUILD
+	  if(retrycount++ > width*height)
+	  	throw LIBRAW_EXCEPTION_IO_CORRUPT;
+#endif
+	}
       }
     }
 

programming_language: C++
filename: dcraw_common.cpp
change_type: ModificationType.MODIFY
diff: @@ -5727,6 +5727,8 @@ void CLASS xtrans_interpolate(int passes)
 #endif
 
 #ifdef LIBRAW_LIBRARY_BUILD
+  if(width < TS || height < TS)
+	  throw LIBRAW_EXCEPTION_IO_CORRUPT; // too small image
 /* Check against right pattern */
   for (row = 0; row < 6; row++)
 	  for (col = 0; col < 6; col++)
@@ -5735,6 +5737,13 @@ void CLASS xtrans_interpolate(int passes)
   if(cstat[0] < 6 || cstat[0]>10 || cstat[1]< 16
     || cstat[1]>24 || cstat[2]< 6 || cstat[2]>10 || cstat[3])
 	  throw LIBRAW_EXCEPTION_IO_CORRUPT;
+
+ // Init allhex table to unreasonable values
+ for(int i = 0; i < 3; i++)
+  for(int j = 0; j < 3; j++)
+   for(int k = 0; k < 2; k++)
+    for(int l = 0; l < 8; l++)
+     allhex[i][j][k][l]=32700;
 #endif
   cielab(0, 0);
   ndir = 4 << (passes > 1);
@@ -5745,6 +5754,7 @@ void CLASS xtrans_interpolate(int passes)
   drv = (float(*)[TS][TS])(buffer + TS * TS * (ndir * 6 + 6));
   homo = (char(*)[TS][TS])(buffer + TS * TS * (ndir * 10 + 6));
 
+  int minv=0,maxv=0,minh=0,maxh=0;
   /* Map a green hexagon around each non-green pixel and vice versa:	*/
   for (row = 0; row < 3; row++)
     for (col = 0; col < 3; col++)
@@ -5765,11 +5775,25 @@ void CLASS xtrans_interpolate(int passes)
           {
             v = orth[d] * patt[g][c * 2] + orth[d + 1] * patt[g][c * 2 + 1];
             h = orth[d + 2] * patt[g][c * 2] + orth[d + 3] * patt[g][c * 2 + 1];
+	    minv=MIN(v,minv);
+	    maxv=MAX(v,maxv);
+	    minh=MIN(v,minh);
+   	    maxh=MAX(v,maxh);
             allhex[row][col][0][c ^ (g * 2 & d)] = h + v * width;
             allhex[row][col][1][c ^ (g * 2 & d)] = h + v * TS;
           }
       }
 
+#ifdef LIBRAW_LIBRARY_BUILD
+   // Check allhex table initialization
+  for(int i = 0; i < 3; i++)
+    for(int j = 0; j < 3; j++)
+      for(int k = 0; k < 2; k++)
+        for(int l = 0; l < 8; l++)
+	  if(allhex[i][j][k][l]>maxh+maxv*width+1 || allhex[i][j][k][l]<minh+minv*width-1)
+	  throw LIBRAW_EXCEPTION_IO_CORRUPT;
+  int retrycount = 0;
+#endif
   /* Set green1 and green3 to the minimum and maximum allowed values:	*/
   for (row = 2; row < height - 2; row++)
     for (min = ~(max = 0), col = 2; col < width - 2; col++)
@@ -5800,7 +5824,13 @@ void CLASS xtrans_interpolate(int passes)
         break;
       case 2:
         if ((min = ~(max = 0)) && (col += 2) < width - 3 && row > 2)
-          row--;
+	{
+           row--;
+#ifdef LIBRAW_LIBRARY_BUILD
+	  if(retrycount++ > width*height)
+	  	throw LIBRAW_EXCEPTION_IO_CORRUPT;
+#endif
+	}
       }
     }
 

programming_language: C++