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 #include #include +#include #include #include @@ -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);