summaryrefslogtreecommitdiff
path: root/pngread.c
diff options
context:
space:
mode:
authorJohn Bowler <jbowler@acm.org>2016-06-11 14:11:09 -0500
committerGlenn Randers-Pehrson <glennrp at users.sourceforge.net>2016-06-11 14:11:09 -0500
commit5c6b7e177cb59a20ecd97b4f30aee5ebe302b9dc (patch)
tree64137eb7f20f704008b24cd72713a1e4a1ef9cdb /pngread.c
parent428f5ddabd23d784c688fd1a27197a776beba09d (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.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/pngread.c b/pngread.c
index 0ff623802..6752db2af 100644
--- a/pngread.c
+++ b/pngread.c
@@ -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))