diff --git a/ANNOUNCE b/ANNOUNCE index 98954963c..3c86884b8 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,4 +1,4 @@ -Libpng 1.6.30beta02 - April 1, 2017 +Libpng 1.6.30beta02 - April 21, 2017 This is not intended to be a public release. It will be replaced within a few weeks by a public version or by another test version. @@ -32,7 +32,10 @@ Version 1.6.30beta01 [April 1, 2017] Silence clang -Wcomma and const drop warnings (Viktor Szakats). Update Sourceforge URLs in documentation (https instead of http). -Version 1.6.30beta02 [April 1, 2017] +Version 1.6.30beta02 [April 21, 2017] + Document need to check for integer overflow when allocating a pixel + buffer for multiple rows in contrib/gregbook, contrib/pngminus, + example.c, and in the manual (suggested by Jaeseung Choi). Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/CHANGES b/CHANGES index 13cfeeada..9bd87850d 100644 --- a/CHANGES +++ b/CHANGES @@ -5827,7 +5827,10 @@ Version 1.6.30beta01 [April 1, 2017] Silence clang -Wcomma and const drop warnings (Viktor Szakats). Update Sourceforge URLs in documentation (https instead of http). -Version 1.6.30beta02 [April 16, 2017] +Version 1.6.30beta02 [April 21, 2017] + Document need to check for integer overflow when allocating a pixel + buffer for multiple rows in contrib/gregbook, contrib/pngminus, + example.c, and in the manual (suggested by Jaeseung Choi). Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/contrib/gregbook/readpng.c b/contrib/gregbook/readpng.c index 9167403e5..e6a01c6f7 100644 --- a/contrib/gregbook/readpng.c +++ b/contrib/gregbook/readpng.c @@ -264,6 +264,12 @@ uch *readpng_get_image(double display_exponent, int *pChannels, ulg *pRowbytes) *pRowbytes = rowbytes = png_get_rowbytes(png_ptr, info_ptr); *pChannels = (int)png_get_channels(png_ptr, info_ptr); + /* Guard against integer overflow */ + if (height > ((size_t)(-1))/rowbytes) { + fprintf(stderr, "readpng: image_data buffer would be too large\n", + return NULL; + } + if ((image_data = (uch *)malloc(rowbytes*height)) == NULL) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return NULL; diff --git a/contrib/gregbook/readppm.c b/contrib/gregbook/readppm.c index 7fefc3943..3a41f3e1d 100644 --- a/contrib/gregbook/readppm.c +++ b/contrib/gregbook/readppm.c @@ -154,12 +154,17 @@ uch *readpng_get_image(double display_exponent, int *pChannels, ulg *pRowbytes) *pRowbytes = rowbytes = channels*width; *pChannels = channels; - if ((image_data = (uch *)malloc(rowbytes*height)) == NULL) { + Trace((stderr, "readpng_get_image: rowbytes = %ld, height = %ld\n", rowbytes, height)); + + /* Guard against integer overflow */ + if (height > ((size_t)(-1))/rowbytes) { + fprintf(stderr, PROGNAME ": image_data buffer would be too large\n", return NULL; } - Trace((stderr, "readpng_get_image: rowbytes = %ld, height = %ld\n", rowbytes, height)); - + if ((image_data = (uch *)malloc(rowbytes*height)) == NULL) { + return NULL; + } /* now we can go ahead and just read the whole image */ diff --git a/contrib/gregbook/rpng-win.c b/contrib/gregbook/rpng-win.c index cd5543937..313beaff1 100644 --- a/contrib/gregbook/rpng-win.c +++ b/contrib/gregbook/rpng-win.c @@ -496,6 +496,12 @@ static int rpng_win_create_window(HINSTANCE hInst, int showmode) wimage_rowbytes = ((3*image_width + 3L) >> 2) << 2; + /* Guard against integer overflow */ + if (image_height > ((size_t)(-1))/wimage_rowbytes) { + fprintf(stderr, PROGNAME ": image_data buffer would be too large\n", + return 4; /* fail */ + } + if (!(dib = (uch *)malloc(sizeof(BITMAPINFOHEADER) + wimage_rowbytes*image_height))) { diff --git a/contrib/gregbook/rpng2-win.c b/contrib/gregbook/rpng2-win.c index c924c1c6c..8720bb011 100644 --- a/contrib/gregbook/rpng2-win.c +++ b/contrib/gregbook/rpng2-win.c @@ -650,6 +650,13 @@ static void rpng2_win_init() Trace((stderr, " width = %ld\n", rpng2_info.width)) Trace((stderr, " height = %ld\n", rpng2_info.height)) + /* Guard against integer overflow */ + if (rpng2_info.height > ((size_t)(-1))/rowbytes) { + fprintf(stderr, PROGNAME ": image_data buffer would be too large\n", + readpng2_cleanup(&rpng2_info); + return; + } + rpng2_info.image_data = (uch *)malloc(rowbytes * rpng2_info.height); if (!rpng2_info.image_data) { readpng2_cleanup(&rpng2_info); diff --git a/contrib/gregbook/rpng2-x.c b/contrib/gregbook/rpng2-x.c index 0c8ddeba2..2585203b4 100644 --- a/contrib/gregbook/rpng2-x.c +++ b/contrib/gregbook/rpng2-x.c @@ -780,6 +780,13 @@ static void rpng2_x_init(void) Trace((stderr, " width = %ld\n", rpng2_info.width)) Trace((stderr, " height = %ld\n", rpng2_info.height)) + /* Guard against integer overflow */ + if (rpng2_info.height > ((size_t)(-1))/rpng2_info.rowbytes) { + fprintf(stderr, PROGNAME ": image_data buffer would be too large\n"); + readpng2_cleanup(&rpng2_info); + return; + } + rpng2_info.image_data = (uch *)malloc(rowbytes * rpng2_info.height); if (!rpng2_info.image_data) { readpng2_cleanup(&rpng2_info); diff --git a/contrib/gregbook/wpng.c b/contrib/gregbook/wpng.c index a06e3529e..3b5b8118d 100644 --- a/contrib/gregbook/wpng.c +++ b/contrib/gregbook/wpng.c @@ -702,7 +702,17 @@ int main(int argc, char **argv) if (wpng_info.interlaced) { long i; ulg bytes; - ulg image_bytes = rowbytes * wpng_info.height; /* overflow? */ + ulg image_bytes; + + /* Guard against integer overflow */ + if (wpng_info_height > ((size_t)(-1)/rowbytes) { + fprintf(stderr, PROGNAME ": image_data buffer too large\n"); + writepng_cleanup(&wpng_info); + wpng_cleanup(); + exit(5); + } + + image_bytes = rowbytes * wpng_info.height; /* overflow? */ wpng_info.image_data = (uch *)malloc(image_bytes); wpng_info.row_pointers = (uch **)malloc(wpng_info.height*sizeof(uch *)); diff --git a/contrib/pngminus/png2pnm.c b/contrib/pngminus/png2pnm.c index 995fddf37..4f01a5ebd 100644 --- a/contrib/pngminus/png2pnm.c +++ b/contrib/pngminus/png2pnm.c @@ -320,6 +320,10 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, /* row_bytes is the width x number of channels x (bit-depth / 8) */ row_bytes = png_get_rowbytes (png_ptr, info_ptr); + if (height > ((size_t)(-1))/row_bytes) /* too big */ { + png_destroy_read_struct (&png_ptr, &info_ptr, NULL); + return FALSE; + } if ((png_pixels = (png_byte *) malloc (row_bytes * height * sizeof (png_byte))) == NULL) { png_destroy_read_struct (&png_ptr, &info_ptr, NULL); diff --git a/contrib/pngminus/pnm2png.c b/contrib/pngminus/pnm2png.c index 5de828a74..7346d57a7 100644 --- a/contrib/pngminus/pnm2png.c +++ b/contrib/pngminus/pnm2png.c @@ -373,6 +373,9 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace, /* row_bytes is the width x number of channels x (bit-depth / 8) */ row_bytes = width * channels * ((bit_depth <= 8) ? 1 : 2); + if (height > ((size_t)(-1))/row_bytes) /* too big */ { + return FALSE; + } if ((png_pixels = (png_byte *) malloc (row_bytes * height * sizeof (png_byte))) == NULL) return FALSE; diff --git a/libpng-manual.txt b/libpng-manual.txt index a3392167d..c3ee45b74 100644 --- a/libpng-manual.txt +++ b/libpng-manual.txt @@ -1,6 +1,6 @@ libpng-manual.txt - A description on how to use and modify libpng - libpng version 1.6.30beta02 - April 3, 2017 + libpng version 1.6.30beta02 - April 19, 2017 Updated and distributed by Glenn Randers-Pehrson Copyright (c) 1998-2016 Glenn Randers-Pehrson @@ -11,7 +11,7 @@ libpng-manual.txt - A description on how to use and modify libpng Based on: - libpng versions 0.97, January 1998, through 1.6.30beta02 - April 3, 2017 + libpng versions 0.97, January 1998, through 1.6.30beta02 - April 19, 2017 Updated and distributed by Glenn Randers-Pehrson Copyright (c) 1998-2016 Glenn Randers-Pehrson @@ -1190,7 +1190,20 @@ row_pointers prior to calling png_read_png() with png_set_rows(png_ptr, info_ptr, &row_pointers); Alternatively you could allocate your image in one big block and define -row_pointers[i] to point into the proper places in your block. +row_pointers[i] to point into the proper places in your block, but first +be sure that your platform is able to allocate such a large buffer: + + /* Guard against integer overflow */ + if (height > PNG_SIZE_MAX/(width*pixel_size)) { + png_error(png_ptr,"image_data buffer would be too large"); + } + + png_bytep buffer=png_malloc(png_ptr,height*width*pixel_size); + + for (int i=0; i PNG_SIZE_MAX/(width*pixel_size)) { + png_error(png_ptr,"image_data buffer would be too large"); + } + Remember: Before you call png_read_update_info(), the png_get_*() functions return the values corresponding to the original PNG image. After you call png_read_update_info the values refer to the image diff --git a/libpng.3 b/libpng.3 index 3079c7dca..2466e347d 100644 --- a/libpng.3 +++ b/libpng.3 @@ -1,4 +1,4 @@ -.TH LIBPNG 3 "April 3, 2017" +.TH LIBPNG 3 "April 19, 2017" .SH NAME libpng \- Portable Network Graphics (PNG) Reference Library 1.6.30beta02 .SH SYNOPSIS @@ -510,7 +510,7 @@ Following is a copy of the libpng-manual.txt file that accompanies libpng. .SH LIBPNG.TXT libpng-manual.txt - A description on how to use and modify libpng - libpng version 1.6.30beta02 - April 3, 2017 + libpng version 1.6.30beta02 - April 19, 2017 Updated and distributed by Glenn Randers-Pehrson Copyright (c) 1998-2016 Glenn Randers-Pehrson @@ -521,7 +521,7 @@ libpng-manual.txt - A description on how to use and modify libpng Based on: - libpng versions 0.97, January 1998, through 1.6.30beta02 - April 3, 2017 + libpng versions 0.97, January 1998, through 1.6.30beta02 - April 19, 2017 Updated and distributed by Glenn Randers-Pehrson Copyright (c) 1998-2016 Glenn Randers-Pehrson @@ -1700,7 +1700,20 @@ row_pointers prior to calling png_read_png() with png_set_rows(png_ptr, info_ptr, &row_pointers); Alternatively you could allocate your image in one big block and define -row_pointers[i] to point into the proper places in your block. +row_pointers[i] to point into the proper places in your block, but first +be sure that your platform is able to allocate such a large buffer: + + /* Guard against integer overflow */ + if (height > PNG_SIZE_MAX/(width*pixel_size)) { + png_error(png_ptr,"image_data buffer would be too large"); + } + + png_bytep buffer=png_malloc(png_ptr,height*width*pixel_size); + + for (int i=0; i PNG_SIZE_MAX/(width*pixel_size)) { + png_error(png_ptr,"image_data buffer would be too large"); + } + Remember: Before you call png_read_update_info(), the png_get_*() functions return the values corresponding to the original PNG image. After you call png_read_update_info the values refer to the image @@ -6026,7 +6049,7 @@ possible without all of you. Thanks to Frank J. T. Wojcik for helping with the documentation. -Libpng version 1.6.30beta02 - April 3, 2017: +Libpng version 1.6.30beta02 - April 19, 2017: Initially created in 1995 by Guy Eric Schalnat, then of Group 42, Inc. Currently maintained by Glenn Randers-Pehrson (glennrp at users.sourceforge.net). @@ -6051,7 +6074,7 @@ this sentence. This code is released under the libpng license. -libpng versions 1.0.7, July 1, 2000 through 1.6.30beta02, April 3, 2017 are +libpng versions 1.0.7, July 1, 2000 through 1.6.30beta02, April 19, 2017 are Copyright (c) 2000-2002, 2004, 2006-2017 Glenn Randers-Pehrson, are derived from libpng-1.0.6, and are distributed according to the same disclaimer and license as libpng-1.0.6 with the following individuals @@ -6179,7 +6202,7 @@ files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31). Glenn Randers-Pehrson glennrp at users.sourceforge.net -April 3, 2017 +April 19, 2017 .\" end of man page diff --git a/libpngpf.3 b/libpngpf.3 index 0844b7323..93b781c26 100644 --- a/libpngpf.3 +++ b/libpngpf.3 @@ -1,4 +1,4 @@ -.TH LIBPNGPF 3 "April 1, 2017" +.TH LIBPNGPF 3 "April 19, 2017" .SH NAME libpng \- Portable Network Graphics (PNG) Reference Library 1.6.30beta02 (private functions)