CVE-2013-7456 (published 2016-08-07T10:59Z)

gd_interpolation.c in the GD Graphics Library (aka libgd) before 2.1.1, as used in PHP before 5.5.36, 5.6.x before 5.6.22, and 7.x before 7.0.7, allows remote attackers to cause a denial of service (out-of-bounds read) or possibly have unspecified other impact via a crafted image that is mishandled by the imagescale function.

Severity: MEDIUM
CVSS v2 base score: 6.8 (AV:N/AC:M/Au:N/C:P/I:P/A:P)
CVSS v3 base score: 7.6, HIGH (CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/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/libgd/libgd
commit_details: repo_url: https://github.com/libgd/libgd
author: Chris Reuter
author_date: 2013-09-23 18:03:08-04:00
msg: Fixed memory overrun bug in gdImageScaleTwoPass

_gdContributionsCalc would compute a window size and then adjust
the left and right positions of the window to make a window within
that size.  However, it was storing the values in the struct *before*
it made the adjustment.  This change fixes that.
repository: repo_url: https://github.com/libgd/libgd
repo_name: libgd/libgd
description: GD Graphics Library
repo_language: C
owner: libgd
file_changes: filename: gd_interpolation.c
change_type: ModificationType.MODIFY
diff: @@ -953,9 +953,6 @@ static inline LineContribType *_gdContributionsCalc(unsigned int line_size, unsi
 		double dTotalWeight = 0.0;
 		int iSrc;
 
-		res->ContribRow[u].Left = iLeft;
-		res->ContribRow[u].Right = iRight;
-
 		/* Cut edge points to fit in filter window in case of spill-off */
 		if (iRight - iLeft + 1 > windows_size)  {
 			if (iLeft < ((int)src_size - 1 / 2))  {
@@ -965,6 +962,9 @@ static inline LineContribType *_gdContributionsCalc(unsigned int line_size, unsi
 			}
 		}
 
+		res->ContribRow[u].Left = iLeft;
+		res->ContribRow[u].Right = iRight;
+
 		for (iSrc = iLeft; iSrc <= iRight; iSrc++) {
 			dTotalWeight += (res->ContribRow[u].Weights[iSrc-iLeft] =  scale_f_d * (*pFilter)(scale_f_d * (dCenter - (double)iSrc)));
 		}

programming_language: C
repo_url: https://github.com/php/php-src
commit_details: repo_url: https://github.com/php/php-src
author: Stanislav Malyshev
author_date: 2016-05-23 00:28:02-07:00
msg: Fixed bug #72227: imagescale out-of-bounds read

Ported from https://github.com/libgd/libgd/commit/4f65a3e4eedaffa1efcf9ee1eb08f0b504fbc31a
repository: repo_url: https://github.com/php/php-src
repo_name: php/php-src
description: The PHP Interpreter
repo_language: C
owner: php
file_changes: filename: gd_interpolation.c
change_type: ModificationType.MODIFY
diff: @@ -39,8 +39,8 @@
 	downscaling using the fixed point implementations are usually much faster
 	than the existing gdImageCopyResampled while having a similar or better
 	quality.
-	
-	For image rotations, the optimized versions have a lazy antialiasing for 
+
+	For image rotations, the optimized versions have a lazy antialiasing for
 	the edges of the images. For a much better antialiased result, the affine
 	function is recommended.
 */
@@ -633,7 +633,7 @@ static inline int _color_blend (const int dst, const int src)
 	}
 }
 
-static inline int _setEdgePixel(const gdImagePtr src, unsigned int x, unsigned int y, gdFixed coverage, const int bgColor) 
+static inline int _setEdgePixel(const gdImagePtr src, unsigned int x, unsigned int y, gdFixed coverage, const int bgColor)
 {
 	const gdFixed f_127 = gd_itofx(127);
 	register int c = src->tpixels[y][x];
@@ -934,9 +934,6 @@ static inline LineContribType *_gdContributionsCalc(unsigned int line_size, unsi
         double dTotalWeight = 0.0;
 		int iSrc;
 
-        res->ContribRow[u].Left = iLeft;
-        res->ContribRow[u].Right = iRight;
-
         /* Cut edge points to fit in filter window in case of spill-off */
         if (iRight - iLeft + 1 > windows_size)  {
             if (iLeft < ((int)src_size - 1 / 2))  {
@@ -946,6 +943,9 @@ static inline LineContribType *_gdContributionsCalc(unsigned int line_size, unsi
             }
         }
 
+        res->ContribRow[u].Left = iLeft;
+        res->ContribRow[u].Right = iRight;
+
         for (iSrc = iLeft; iSrc <= iRight; iSrc++) {
             dTotalWeight += (res->ContribRow[u].Weights[iSrc-iLeft] =  scale_f_d * (*pFilter)(scale_f_d * (dCenter - (double)iSrc)));
         }
@@ -2273,7 +2273,7 @@ int gdTransformAffineGetImage(gdImagePtr *dst,
 	if (!src->trueColor) {
 		gdImagePaletteToTrueColor(src);
 	}
-	
+
 	/* Translate to dst origin (0,0) */
 	gdAffineTranslate(m, -bbox.x, -bbox.y);
 	gdAffineConcat(m, affine, m);
@@ -2332,7 +2332,7 @@ int gdTransformAffineCopy(gdImagePtr dst,
 	if (src->interpolation_id == GD_BILINEAR_FIXED || src->interpolation_id == GD_BICUBIC_FIXED || src->interpolation_id == GD_NEAREST_NEIGHBOUR) {
 		interpolation_id_bak = src->interpolation_id;
 		interpolation_bak = src->interpolation;
-		
+
 		gdImageSetInterpolationMethod(src, GD_BICUBIC);
 	}
 

programming_language: C
filename: bug72227.phpt
change_type: ModificationType.ADD
diff: @@ -0,0 +1,15 @@
+--TEST--
+Bug #72227: imagescale out-of-bounds read
+--SKIPIF--
+<?php
+	if (!extension_loaded('gd')) die("skip gd extension not available\n");
+?>
+--FILE--
+<?php
+
+$img = imagecreatetruecolor ( 100, 100);
+imagescale($img, 13, 1, IMG_BICUBIC);
+?>
+DONE
+--EXPECT--
+DONE
\ No newline at end of file

programming_language: PHP