[libpng16] 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).
This commit is contained in:
Glenn Randers-Pehrson 2017-04-22 15:21:58 -05:00
parent 13370c536c
commit 53f22aed41
13 changed files with 118 additions and 18 deletions

View File

@ -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 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. 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). Silence clang -Wcomma and const drop warnings (Viktor Szakats).
Update Sourceforge URLs in documentation (https instead of http). 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 Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit (subscription required; visit

View File

@ -5827,7 +5827,10 @@ Version 1.6.30beta01 [April 1, 2017]
Silence clang -Wcomma and const drop warnings (Viktor Szakats). Silence clang -Wcomma and const drop warnings (Viktor Szakats).
Update Sourceforge URLs in documentation (https instead of http). 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 Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit (subscription required; visit

View File

@ -264,6 +264,12 @@ uch *readpng_get_image(double display_exponent, int *pChannels, ulg *pRowbytes)
*pRowbytes = rowbytes = png_get_rowbytes(png_ptr, info_ptr); *pRowbytes = rowbytes = png_get_rowbytes(png_ptr, info_ptr);
*pChannels = (int)png_get_channels(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) { if ((image_data = (uch *)malloc(rowbytes*height)) == NULL) {
png_destroy_read_struct(&png_ptr, &info_ptr, NULL); png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return NULL; return NULL;

View File

@ -154,12 +154,17 @@ uch *readpng_get_image(double display_exponent, int *pChannels, ulg *pRowbytes)
*pRowbytes = rowbytes = channels*width; *pRowbytes = rowbytes = channels*width;
*pChannels = channels; *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; 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 */ /* now we can go ahead and just read the whole image */

View File

@ -496,6 +496,12 @@ static int rpng_win_create_window(HINSTANCE hInst, int showmode)
wimage_rowbytes = ((3*image_width + 3L) >> 2) << 2; 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) + if (!(dib = (uch *)malloc(sizeof(BITMAPINFOHEADER) +
wimage_rowbytes*image_height))) wimage_rowbytes*image_height)))
{ {

View File

@ -650,6 +650,13 @@ static void rpng2_win_init()
Trace((stderr, " width = %ld\n", rpng2_info.width)) Trace((stderr, " width = %ld\n", rpng2_info.width))
Trace((stderr, " height = %ld\n", rpng2_info.height)) 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); rpng2_info.image_data = (uch *)malloc(rowbytes * rpng2_info.height);
if (!rpng2_info.image_data) { if (!rpng2_info.image_data) {
readpng2_cleanup(&rpng2_info); readpng2_cleanup(&rpng2_info);

View File

@ -780,6 +780,13 @@ static void rpng2_x_init(void)
Trace((stderr, " width = %ld\n", rpng2_info.width)) Trace((stderr, " width = %ld\n", rpng2_info.width))
Trace((stderr, " height = %ld\n", rpng2_info.height)) 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); rpng2_info.image_data = (uch *)malloc(rowbytes * rpng2_info.height);
if (!rpng2_info.image_data) { if (!rpng2_info.image_data) {
readpng2_cleanup(&rpng2_info); readpng2_cleanup(&rpng2_info);

View File

@ -702,7 +702,17 @@ int main(int argc, char **argv)
if (wpng_info.interlaced) { if (wpng_info.interlaced) {
long i; long i;
ulg bytes; 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.image_data = (uch *)malloc(image_bytes);
wpng_info.row_pointers = (uch **)malloc(wpng_info.height*sizeof(uch *)); wpng_info.row_pointers = (uch **)malloc(wpng_info.height*sizeof(uch *));

View File

@ -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 is the width x number of channels x (bit-depth / 8) */
row_bytes = png_get_rowbytes (png_ptr, info_ptr); 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 *) if ((png_pixels = (png_byte *)
malloc (row_bytes * height * sizeof (png_byte))) == NULL) { malloc (row_bytes * height * sizeof (png_byte))) == NULL) {
png_destroy_read_struct (&png_ptr, &info_ptr, NULL); png_destroy_read_struct (&png_ptr, &info_ptr, NULL);

View File

@ -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 is the width x number of channels x (bit-depth / 8) */
row_bytes = width * channels * ((bit_depth <= 8) ? 1 : 2); 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 *) if ((png_pixels = (png_byte *)
malloc (row_bytes * height * sizeof (png_byte))) == NULL) malloc (row_bytes * height * sizeof (png_byte))) == NULL)
return FALSE; return FALSE;

View File

@ -1,6 +1,6 @@
libpng-manual.txt - A description on how to use and modify libpng 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 Updated and distributed by Glenn Randers-Pehrson
<glennrp at users.sourceforge.net> <glennrp at users.sourceforge.net>
Copyright (c) 1998-2016 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: 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 Updated and distributed by Glenn Randers-Pehrson
Copyright (c) 1998-2016 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); png_set_rows(png_ptr, info_ptr, &row_pointers);
Alternatively you could allocate your image in one big block and define 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<height, i++)
row_pointers[i]=buffer+i*width*pixel_size;
png_set_rows(png_ptr, info_ptr, &row_pointers);
If you use png_set_rows(), the application is responsible for freeing If you use png_set_rows(), the application is responsible for freeing
row_pointers (and row_pointers[i], if they were separately allocated). row_pointers (and row_pointers[i], if they were separately allocated).
@ -2146,6 +2159,16 @@ are allocating one large chunk, you will need to build an
array of pointers to each row, as it will be needed for some array of pointers to each row, as it will be needed for some
of the functions below. of the functions below.
Be sure that your platform can allocate the buffer that you'll need.
libpng internally checks for oversize width, but you'll need to
do your own check for number_of_rows*width*pixel_size if you are using
a multiple-row buffer:
/* Guard against integer overflow */
if (number_of_rows > 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_*() Remember: Before you call png_read_update_info(), the png_get_*()
functions return the values corresponding to the original PNG image. functions return the values corresponding to the original PNG image.
After you call png_read_update_info the values refer to the image After you call png_read_update_info the values refer to the image

View File

@ -1,4 +1,4 @@
.TH LIBPNG 3 "April 3, 2017" .TH LIBPNG 3 "April 19, 2017"
.SH NAME .SH NAME
libpng \- Portable Network Graphics (PNG) Reference Library 1.6.30beta02 libpng \- Portable Network Graphics (PNG) Reference Library 1.6.30beta02
.SH SYNOPSIS .SH SYNOPSIS
@ -510,7 +510,7 @@ Following is a copy of the libpng-manual.txt file that accompanies libpng.
.SH LIBPNG.TXT .SH LIBPNG.TXT
libpng-manual.txt - A description on how to use and modify libpng 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 Updated and distributed by Glenn Randers-Pehrson
<glennrp at users.sourceforge.net> <glennrp at users.sourceforge.net>
Copyright (c) 1998-2016 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: 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 Updated and distributed by Glenn Randers-Pehrson
Copyright (c) 1998-2016 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); png_set_rows(png_ptr, info_ptr, &row_pointers);
Alternatively you could allocate your image in one big block and define 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<height, i++)
row_pointers[i]=buffer+i*width*pixel_size;
png_set_rows(png_ptr, info_ptr, &row_pointers);
If you use png_set_rows(), the application is responsible for freeing If you use png_set_rows(), the application is responsible for freeing
row_pointers (and row_pointers[i], if they were separately allocated). row_pointers (and row_pointers[i], if they were separately allocated).
@ -2656,6 +2669,16 @@ are allocating one large chunk, you will need to build an
array of pointers to each row, as it will be needed for some array of pointers to each row, as it will be needed for some
of the functions below. of the functions below.
Be sure that your platform can allocate the buffer that you'll need.
libpng internally checks for oversize width, but you'll need to
do your own check for number_of_rows*width*pixel_size if you are using
a multiple-row buffer:
/* Guard against integer overflow */
if (number_of_rows > 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_*() Remember: Before you call png_read_update_info(), the png_get_*()
functions return the values corresponding to the original PNG image. functions return the values corresponding to the original PNG image.
After you call png_read_update_info the values refer to the 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. 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. Initially created in 1995 by Guy Eric Schalnat, then of Group 42, Inc.
Currently maintained by Glenn Randers-Pehrson (glennrp at users.sourceforge.net). 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. 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 Copyright (c) 2000-2002, 2004, 2006-2017 Glenn Randers-Pehrson, are
derived from libpng-1.0.6, and are distributed according to the same 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 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 Glenn Randers-Pehrson
glennrp at users.sourceforge.net glennrp at users.sourceforge.net
April 3, 2017 April 19, 2017
.\" end of man page .\" end of man page

View File

@ -1,4 +1,4 @@
.TH LIBPNGPF 3 "April 1, 2017" .TH LIBPNGPF 3 "April 19, 2017"
.SH NAME .SH NAME
libpng \- Portable Network Graphics (PNG) Reference Library 1.6.30beta02 libpng \- Portable Network Graphics (PNG) Reference Library 1.6.30beta02
(private functions) (private functions)