summaryrefslogtreecommitdiffstats
path: root/libraries/libglpng/patches/libglpng-1.45-CVE-2010-1519.patch
blob: 04869bbd998b4857149f4e4a263f54e498cdf88c (plain)
diff -up libglpng-1.45.orig/src/glpng.c.cve libglpng-1.45.orig/src/glpng.c
--- libglpng-1.45.orig/src/glpng.c.cve	2010-09-10 14:13:37.105046660 +0200
+++ libglpng-1.45.orig/src/glpng.c	2010-09-10 14:14:46.158045715 +0200
@@ -28,6 +28,7 @@
 #include <GL/glpng.h>
 #include <GL/gl.h>
 #include <stdlib.h>
+#include <stdint.h>
 #include <math.h>
 #include <png.h>
 
@@ -259,9 +260,9 @@ int APIENTRY pngLoadRawF(FILE *fp, pngRa
 	png_structp png;
 	png_infop   info;
 	png_infop   endinfo;
-	png_bytep   data;
-   png_bytep  *row_p;
-   double	fileGamma;
+	png_bytep   data = NULL;
+	png_bytep  *row_p = NULL;
+	double      fileGamma;
 
 	png_uint_32 width, height;
 	int depth, color;
@@ -274,13 +275,19 @@ int APIENTRY pngLoadRawF(FILE *fp, pngRa
 	if (!png_check_sig(header, 8)) return 0;
 
 	png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+	if (!png) return 0;
 	info = png_create_info_struct(png);
+	if (!info) return 0;
 	endinfo = png_create_info_struct(png);
+	if (!endinfo) return 0;
 
 	// DH: added following lines
 	if (setjmp(png->jmpbuf))
 	{
+error:
 		png_destroy_read_struct(&png, &info, &endinfo);
+		free(data);
+		free(row_p);
 		return 0;
 	}
 	// ~DH
@@ -303,8 +310,16 @@ int APIENTRY pngLoadRawF(FILE *fp, pngRa
 
 	png_read_update_info(png, info);
 
+	/* HDG: We allocate all the png data in one linear array, thus
+	   height * png_get_rowbytes() may not be > PNG_UINT_32_MAX !
+	   This check fixes CVE-2010-1519. */
+	if ((uint64_t)height * png_get_rowbytes(png, info) > PNG_UINT_32_MAX)
+		goto error;
+
 	data = (png_bytep) malloc(png_get_rowbytes(png, info)*height);
 	row_p = (png_bytep *) malloc(sizeof(png_bytep)*height);
+	if (!data || !row_p)
+		goto error;
 
 	for (i = 0; i < height; i++) {
 		if (StandardOrientation)
@@ -315,6 +330,7 @@ int APIENTRY pngLoadRawF(FILE *fp, pngRa
 
 	png_read_image(png, row_p);
 	free(row_p);
+	row_p = NULL;
 
 	if (color == PNG_COLOR_TYPE_PALETTE) {
 		int cols;
@@ -365,9 +381,10 @@ int APIENTRY pngLoadF(FILE *fp, int mipm
 	png_structp png;
 	png_infop   info;
 	png_infop   endinfo;
-	png_bytep   data, data2;
-   png_bytep  *row_p;
-   double	fileGamma;
+	png_bytep   data = NULL;
+	png_bytep   data2 = NULL;
+	png_bytep  *row_p = NULL;
+	double      fileGamma;
 
 	png_uint_32 width, height, rw, rh;
 	int depth, color;
@@ -378,13 +395,20 @@ int APIENTRY pngLoadF(FILE *fp, int mipm
 	if (!png_check_sig(header, 8)) return 0;
 
 	png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+	if (!png) return 0;
 	info = png_create_info_struct(png);
+	if (!info) return 0;
 	endinfo = png_create_info_struct(png);
+	if (!endinfo) return 0;
 
 	// DH: added following lines
 	if (setjmp(png->jmpbuf))
 	{
+error:
 		png_destroy_read_struct(&png, &info, &endinfo);
+		free(data);
+		free(data2);
+		free(row_p);
 		return 0;
 	}
 	// ~DH
@@ -442,8 +466,16 @@ int APIENTRY pngLoadF(FILE *fp, int mipm
 
 	png_read_update_info(png, info);
 
+	/* HDG: We allocate all the png data in one linear array, thus
+	   height * png_get_rowbytes() may not be > PNG_UINT_32_MAX !
+	   This check fixes CVE-2010-1519. */
+	if ((uint64_t)height * png_get_rowbytes(png, info) > PNG_UINT_32_MAX)
+		goto error;
+
 	data = (png_bytep) malloc(png_get_rowbytes(png, info)*height);
 	row_p = (png_bytep *) malloc(sizeof(png_bytep)*height);
+	if (!data || !row_p)
+		goto error;
 
 	for (i = 0; i < height; i++) {
 		if (StandardOrientation)
@@ -454,6 +486,7 @@ int APIENTRY pngLoadF(FILE *fp, int mipm
 
 	png_read_image(png, row_p);
 	free(row_p);
+	row_p = NULL;
 
 	rw = SafeSize(width), rh = SafeSize(height);
 
@@ -461,6 +494,8 @@ int APIENTRY pngLoadF(FILE *fp, int mipm
 		const int channels = png_get_rowbytes(png, info)/width;
 
 		data2 = (png_bytep) malloc(rw*rh*channels);
+		if (!data2)
+			goto error;
 
  		/* Doesn't work on certain sizes */
 /* 		if (gluScaleImage(glformat, width, height, GL_UNSIGNED_BYTE, data, rw, rh, GL_UNSIGNED_BYTE, data2) != 0)
@@ -471,6 +506,7 @@ int APIENTRY pngLoadF(FILE *fp, int mipm
 		width = rw, height = rh;
 		free(data);
 		data = data2;
+		data2 = NULL;
 	}
 
 	{ /* OpenGL stuff */
@@ -540,6 +576,12 @@ int APIENTRY pngLoadF(FILE *fp, int mipm
 			png_bytep p, endp, q;
 			int r, g, b, a;
 
+			/* HDG another potential 32 bit address overflow, the
+			   original png had 3 channels and we are going to
+			   4 channels now! */
+			if ((uint64_t)width * height > (PNG_UINT_32_MAX >> 2))
+				goto error;
+
 			p = data, endp = p+width*height*3;
 			q = data2 = (png_bytep) malloc(sizeof(png_byte)*width*height*4);