diff options
author | John Bowler <jbowler@acm.org> | 2016-06-11 14:11:09 -0500 |
---|---|---|
committer | Glenn Randers-Pehrson <glennrp at users.sourceforge.net> | 2016-06-11 14:11:09 -0500 |
commit | 5c6b7e177cb59a20ecd97b4f30aee5ebe302b9dc (patch) | |
tree | 64137eb7f20f704008b24cd72713a1e4a1ef9cdb /pngread.c | |
parent | 428f5ddabd23d784c688fd1a27197a776beba09d (diff) |
[libpng16] Avoid potential overflow of the PNG_IMAGE_SIZE macro. This macro
is not used within libpng, but is used in some of the examples.
Diffstat (limited to 'pngread.c')
-rw-r--r-- | pngread.c | 25 |
1 files changed, 24 insertions, 1 deletions
@@ -4087,6 +4087,12 @@ png_image_finish_read(png_imagep image, png_const_colorp background, */ const unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format); + /* The following checks just the 'row_stride' calculation to ensure it + * fits in a signed 32-bit value. Because channels/components can be + * either 1 or 2 bytes in size the length of a row can still overflow 32 + * bits; this is just to verify that the 'row_stride' argument can be + * represented. + */ if (image->width <= 0x7FFFFFFFU/channels) /* no overflow */ { png_uint_32 check; @@ -4101,13 +4107,30 @@ png_image_finish_read(png_imagep image, png_const_colorp background, else check = row_stride; + /* This verifies 'check', the absolute value of the actual stride + * passed in and detects overflow in the application calculation (i.e. + * if the app did actually pass in a non-zero 'row_stride'. + */ if (image->opaque != NULL && buffer != NULL && check >= png_row_stride) { /* Now check for overflow of the image buffer calculation; this * limits the whole image size to 32 bits for API compatibility with * the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro. + * + * The PNG_IMAGE_BUFFER_SIZE macro is: + * + * (PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)*height*(row_stride)) + * + * And the component size is always 1 or 2, so make sure that the + * number of *bytes* that the application is saying are available + * does actually fit into a 32-bit number. + * + * NOTE: this will be changed in 1.7 because PNG_IMAGE_BUFFER_SIZE + * will be changed to use png_alloc_size_t; bigger images can be + * accomodated on 64-bit systems. */ - if (image->height <= 0xFFFFFFFF/png_row_stride) + if (image->height <= + 0xFFFFFFFFU/PNG_IMAGE_PIXEL_COMPONENT_SIZE(image->format)/check) { if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 || (image->colormap_entries > 0 && colormap != NULL)) |