--- gd-1.8.4/gd_png.c.security 2001-02-06 20:44:02.000000000 +0100 +++ gd-1.8.4/gd_png.c 2004-11-04 17:21:10.000000000 +0100 @@ -342,11 +342,20 @@ /* allocate space for the PNG image data */ rowbytes = png_get_rowbytes(png_ptr, info_ptr); + if (overflow2(rowbytes, height)) { + png_destroy_read_struct (&png_ptr, &info_ptr, NULL); + return NULL; + } if ((image_data = (png_bytep)gdMalloc(rowbytes*height)) == NULL) { fprintf(stderr, "gd-png error: cannot allocate image data\n"); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return NULL; } + if (overflow2(height, sizeof (png_bytep))) { + png_destroy_read_struct (&png_ptr, &info_ptr, NULL); + gdFree (image_data); + return NULL; + } if ((row_pointers = (png_bytepp)gdMalloc(height*sizeof(png_bytep))) == NULL) { fprintf(stderr, "gd-png error: cannot allocate row pointers\n"); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); @@ -577,15 +586,20 @@ * interlaced images, but interlacing causes some serious complications. */ if (remap) { png_bytep *row_pointers; + if (overflow2(sizeof (png_bytep), height)) { + return; + } row_pointers = gdMalloc(sizeof(png_bytep) * height); if (row_pointers == NULL) { fprintf(stderr, "gd-png error: unable to allocate row_pointers\n"); + return; } for (j = 0; j < height; ++j) { if ((row_pointers[j] = (png_bytep)gdMalloc(width)) == NULL) { fprintf(stderr, "gd-png error: unable to allocate rows\n"); for (i = 0; i < j; ++i) gdFree(row_pointers[i]); + gdFree(row_pointers); return; } for (i = 0; i < width; ++i) --- /dev/null 2004-11-04 14:56:21.613583512 +0100 +++ gd-1.8.4/gd_security.c 2004-11-04 17:10:19.000000000 +0100 @@ -0,0 +1,33 @@ +/* + * gd_security.c + * + * Implements buffer overflow check routines. + * + * Written 2004, Phil Knirsch. + * Based on netpbm fixes by Alan Cox. + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include "gd.h" + +int overflow2(int a, int b) +{ + if(a < 0 || b < 0) { + fprintf(stderr, "gd warning: one parameter to a memory allocation multiplication is negative, failing operation gracefully\n"); + return 1; + } + if(b == 0) + return 0; + if(a > INT_MAX / b) { + fprintf(stderr, "gd warning: product of memory allocation multiplication would exceed INT_MAX, failing operation gracefully\n"); + return 1; + } + return 0; +} --- gd-1.8.4/wbmp.c.security 2001-02-06 20:44:02.000000000 +0100 +++ gd-1.8.4/wbmp.c 2004-11-04 17:55:01.000000000 +0100 @@ -108,6 +108,16 @@ if ( (wbmp = (Wbmp *) gdMalloc( sizeof(Wbmp) )) == NULL) return (NULL); + if (overflow2(sizeof(int), width)) + { + gdFree( wbmp ); + return (NULL); + } + if (overflow2(sizeof(int)*width, height)) + { + gdFree( wbmp ); + return (NULL); + } if ( (wbmp->bitmap = (int *) gdMalloc( sizeof(int)*width*height )) == NULL) { gdFree( wbmp ); @@ -167,7 +177,9 @@ printf("W: %d, H: %d\n", wbmp->width, wbmp->height); #endif - if ( (wbmp->bitmap = (int *) gdMalloc( sizeof(int)*wbmp->width*wbmp->height )) == NULL) + if ( overflow2(sizeof (int), wbmp->width) || + overflow2(sizeof (int) * wbmp->width, wbmp->height) || + (wbmp->bitmap = (int *) gdMalloc( sizeof(int)*wbmp->width*wbmp->height )) == NULL) { gdFree( wbmp ); return (-1); --- gd-1.8.4/gd.c.security 2001-02-06 20:44:01.000000000 +0100 +++ gd-1.8.4/gd.c 2004-11-04 18:04:08.000000000 +0100 @@ -62,6 +62,11 @@ int i; gdImagePtr im; im = (gdImage *) gdMalloc(sizeof(gdImage)); + if (overflow2(sizeof (unsigned char *), sy)) + { + gdFree(im); + return NULL; + } /* NOW ROW-MAJOR IN GD 1.3 */ im->pixels = (unsigned char **) gdMalloc(sizeof(unsigned char *) * sy); im->polyInts = 0; @@ -1240,6 +1245,9 @@ /* We only need to use floating point to determine the correct stretch vector for one line's worth. */ double accum; + if (overflow2(sizeof (int), srcW) || overflow2(sizeof (int), srcH)) { + return; + } stx = (int *) gdMalloc(sizeof(int) * srcW); sty = (int *) gdMalloc(sizeof(int) * srcH); accum = 0; @@ -1371,6 +1379,9 @@ } bytes = (w * h / 8) + 1; im = gdImageCreate(w, h); + if(!im) { + return 0; + } gdImageColorAllocate(im, 255, 255, 255); gdImageColorAllocate(im, 0, 0, 0); x = 0; @@ -1462,6 +1473,9 @@ return; } if (!im->polyAllocated) { + if (overflow2(sizeof (int), n)) { + return; + } im->polyInts = (int *) gdMalloc(sizeof(int) * n); im->polyAllocated = n; } @@ -1469,6 +1483,9 @@ while (im->polyAllocated < n) { im->polyAllocated *= 2; } + if (overflow2(sizeof (int), im->polyAllocated)) { + return; + } im->polyInts = (int *) gdRealloc(im->polyInts, sizeof(int) * im->polyAllocated); } @@ -1534,6 +1551,9 @@ if (im->style) { gdFree(im->style); } + if (overflow2(sizeof (int), noOfPixels)) { + return; + } im->style = (int *) gdMalloc(sizeof(int) * noOfPixels); memcpy(im->style, style, sizeof(int) * noOfPixels); --- gd-1.8.4/gdhelpers.h.security 2001-02-06 20:44:02.000000000 +0100 +++ gd-1.8.4/gdhelpers.h 2004-11-04 18:04:52.000000000 +0100 @@ -13,5 +13,12 @@ void *gdMalloc(size_t size); void *gdRealloc(void *ptr, size_t size); +/* Returns nonzero if multiplying the two quantities will + result in integer overflow. Also returns nonzero if + either quantity is negative. By Phil Knirsch based on + netpbm fixes by Alan Cox. */ + +int overflow2(int a, int b); + #endif /* GDHELPERS_H */ --- gd-1.8.4/gd_io_dp.c.security 2001-02-06 20:44:02.000000000 +0100 +++ gd-1.8.4/gd_io_dp.c 2004-11-04 18:14:06.000000000 +0100 @@ -165,6 +165,9 @@ bytesNeeded = pos; if (bytesNeeded > dp->realSize) { + if (overflow2(dp->realSize, 2)) { + return FALSE; + } if (!gdReallocDynamic(dp,dp->realSize*2)) { dp->dataGood = FALSE; return FALSE; @@ -311,6 +314,9 @@ bytesNeeded = dp->pos + size; if (bytesNeeded > dp->realSize) { + if (overflow2(bytesNeeded, 2)) { + return FALSE; + } if (!gdReallocDynamic(dp,bytesNeeded*2)) { dp->dataGood = FALSE; return FALSE; --- gd-1.8.4/gd_gd.c.security 2001-02-06 20:44:01.000000000 +0100 +++ gd-1.8.4/gd_gd.c 2004-11-04 18:14:53.000000000 +0100 @@ -75,7 +75,9 @@ GD2_DBG(printf("Image is %dx%d\n", *sx, *sy)); im = gdImageCreate(*sx, *sy); - + if (!im) { + goto fail1; + } if (!_gdGetColors(in, im)) { goto fail2; } --- gd-1.8.4/gdxpm.c.security 2001-02-06 20:44:02.000000000 +0100 +++ gd-1.8.4/gdxpm.c 2004-11-04 18:16:08.000000000 +0100 @@ -41,6 +41,9 @@ return 0; number = image.ncolors; + if (overflow2(sizeof (int), number)) { + return 0; + } colors = (int*)gdMalloc(sizeof(int) * number); if (colors == NULL) return(0); @@ -124,11 +127,6 @@ fprintf(stderr,"ARRRGH\n"); } - apixel = (char *)gdMalloc(image.cpp+1); - if (apixel == NULL) - return(0); - apixel[image.cpp] = '\0'; - pointer = image.data; for(i=0;i