CVE-2013-2127: Improper Restriction of Operations within the Bounds of a Memory Buffer (CWE-119)
value: Buffer overflow in the exposure correction code in LibRaw before 0.15.1 allows context-dependent attackers to cause a denial of service (crash) and possibly execute arbitrary code via unspecified vectors.
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.
Published: 2013-08-14T15:55Z
Repository: https://github.com/LibRaw/LibRaw
Language: C++
Files changed: src/libraw_cxx.cpp
Commit date: 2013-05-24 21:24:03 +0400
Commit message: fixed wrong data_maximum calcluation; prevent out-of-buffer in exp_bef

Diff: diff --git a/src/libraw_cxx.cpp b/src/libraw_cxx.cpp
index 7acc076..e36c11a 100644
--- a/src/libraw_cxx.cpp
+++ b/src/libraw_cxx.cpp
@@ -2334,18 +2334,19 @@ int LibRaw::subtract_black()
             int size = S.iheight * S.iwidth;
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
 #define LIM(x,min,max) MAX(min,MIN(x,max))
 #define CLIP(x) LIM(x,0,65535)
-
-            for(i=0; i< size*4; i++)
+			int dmax = 0;
+			for(i=0; i< size*4; i++)
               {
                 int val = imgdata.image[0][i];
                 val -= cblk[i & 3];
                 imgdata.image[0][i] = CLIP(val);
-                if(C.data_maximum < val) C.data_maximum = val;
+                if(dmax < val) dmax = val;
               }
+			C.data_maximum = dmax & 0xffff;
 #undef MIN
 #undef MAX
 #undef LIM
 #undef CLIP
             C.maximum -= C.black;
@@ -2357,13 +2358,14 @@ int LibRaw::subtract_black()
         {
           // Nothing to Do, maximum is already calculated, black level is 0, so no change
           // only calculate channel maximum;
           int idx;
           ushort *p = (ushort*)imgdata.image;
-          C.data_maximum = 0;
+		  int dmax = 0;
           for(idx=0;idx<S.iheight*S.iwidth*4;idx++)
-            if(C.data_maximum < p[idx]) C.data_maximum = p[idx];
+            if(dmax < p[idx]) dmax = p[idx];
+		  C.data_maximum = dmax;
         }
 		return 0;
 	}
 	catch ( LibRaw_exceptions err) {
 		EXCEPTION_HANDLER(err);
@@ -2419,12 +2421,14 @@ void LibRaw::exp_bef(float shift, float smooth)
             imgdata.image[i][1] = lut[imgdata.image[i][1]];
             imgdata.image[i][2] = lut[imgdata.image[i][2]];
             imgdata.image[i][3] = lut[imgdata.image[i][3]];
         }
 
-    C.data_maximum = lut[C.data_maximum];
-    C.maximum = lut[C.maximum];
+	if(C.data_maximum <=TBLN)
+		C.data_maximum = lut[C.data_maximum];
+	if(C.maximum <= TBLN)
+		C.maximum = lut[C.maximum];
     // no need to adjust the minumum, black is already subtracted
     free(lut);
 }
 
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
@@ -2528,11 +2532,11 @@ int LibRaw::dcraw_process(void)
 
         int subtract_inline = !O.bad_pixels && !O.dark_frame && !O.wf_debanding && !(di.decoder_flags & LIBRAW_DECODER_LEGACY) && !IO.zero_is_bad;
 
         raw2image_ex(subtract_inline); // allocate imgdata.image and copy data!
 
-        int save_4color = O.four_color_rgb;
+		int save_4color = O.four_color_rgb;
 
         if (IO.zero_is_bad) 
           {
                 remove_zeroes();
                 SET_PROC_FLAG(LIBRAW_PROGRESS_REMOVE_ZEROES);

Vulnerable code: 
            for(i=0; i< size*4; i++)
                if(C.data_maximum < val) C.data_maximum = val;
          C.data_maximum = 0;
            if(C.data_maximum < p[idx]) C.data_maximum = p[idx];
    C.data_maximum = lut[C.data_maximum];
    C.maximum = lut[C.maximum];
        int save_4color = O.four_color_rgb;
Fixed code: 			int dmax = 0;
			for(i=0; i< size*4; i++)
                if(dmax < val) dmax = val;
			C.data_maximum = dmax & 0xffff;
		  int dmax = 0;
            if(dmax < p[idx]) dmax = p[idx];
		  C.data_maximum = dmax;
	if(C.data_maximum <=TBLN)
		C.data_maximum = lut[C.data_maximum];
	if(C.maximum <= TBLN)
		C.maximum = lut[C.maximum];
		int save_4color = O.four_color_rgb;