From 9d2252921d901d5a0c70e5d605421f7c2d3b43cb Mon Sep 17 00:00:00 2001 From: Glenn Randers-Pehrson Date: Thu, 22 Jan 2015 12:08:18 -0600 Subject: [PATCH] [libpng14] Restored test for maximum allowed image width that was removed from libpng-1.4.13 (fixes CVE-2014-9495 and CVE-2015-0973). --- ANNOUNCE | 4 +++- CHANGES | 4 +++- png.c | 69 +++++++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 57 insertions(+), 20 deletions(-) diff --git a/ANNOUNCE b/ANNOUNCE index f80f508ea..158274e21 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -27,7 +27,9 @@ Other information: Changes since the last public release (1.4.14): -version 1.4.15beta01 [%RDATE%] +version 1.4.15beta01 [January 22, 2015] + Restored test for maximum allowed image width that was removed from + libpng-1.4.13 (fixes CVE-2014-9495 and CVE-2015-0973). Send comments/corrections/commendations to glennrp at users.sourceforge.net or to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/CHANGES b/CHANGES index db5ca4f5d..183a452ea 100644 --- a/CHANGES +++ b/CHANGES @@ -2922,7 +2922,9 @@ version 1.4.14rc02 [November 17, 2014] version 1.4.14 [November 20, 2014] No changes. -version 1.4.15beta01 [%RDATE%] +version 1.4.15beta01 [January 22, 2015] + Restored test for maximum allowed image width that was removed from + libpng-1.4.13 (fixes CVE-2014-9495 and CVE-2015-0973). Send comments/corrections/commendations to glennrp at users.sourceforge.net or to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/png.c b/png.c index 39c2c7868..1e3981a1d 100644 --- a/png.c +++ b/png.c @@ -1,8 +1,8 @@ /* png.c - location for general purpose libpng functions * - * Last changed in libpng 1.4.6 [March 8, 2011] - * Copyright (c) 1998-2011 Glenn Randers-Pehrson + * Last changed in libpng 1.4.15 [%RDATE%] + * Copyright (c) 1998-2015 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -547,13 +547,13 @@ png_get_copyright(png_const_structp png_ptr) #else #ifdef __STDC__ return ((png_charp) PNG_STRING_NEWLINE \ - "libpng version 1.4.15 - %RDATE%" PNG_STRING_NEWLINE \ + "libpng version 1.4.15beta01 - January 22, 2015" PNG_STRING_NEWLINE \ "Copyright (c) 1998-2015 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \ "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ PNG_STRING_NEWLINE); #else - return ((png_charp) "libpng version 1.4.15 - %RDATE%\ + return ((png_charp) "libpng version 1.4.15beta01 - January 22, 2015\ Copyright (c) 1998-2015 Glenn Randers-Pehrson\ Copyright (c) 1996-1997 Andreas Dilger\ Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc."); @@ -770,6 +770,17 @@ png_check_cHRM_fixed(png_structp png_ptr, #endif /* PNG_CHECK_cHRM_SUPPORTED */ #endif /* PNG_cHRM_SUPPORTED */ +#ifdef __GNUC__ +/* This exists solely to work round a warning from GNU C. */ +static int /* PRIVATE */ +png_gt(size_t a, size_t b) +{ + return a > b; +} +#else +# define png_gt(a,b) ((a) > (b)) +#endif + void /* PRIVATE */ png_check_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, @@ -785,9 +796,31 @@ png_check_IHDR(png_structp png_ptr, error = 1; } - if (height == 0) + if (width > PNG_UINT_31_MAX) { - png_warning(png_ptr, "Image height is zero in IHDR"); + png_warning(png_ptr, "Invalid image width in IHDR"); + error = 1; + } + + if (png_gt(((width + 7) & (~7)), + ((PNG_UINT_32_MAX /* Changed to PNG_SIZE_MAX here in libpng-1.5.21 */ + - 48 /* big_row_buf hack */ + - 1) /* filter byte */ + / 8) /* 8-byte RGBA pixels */ + - 1)) /* extra max_pixel_depth pad */ + { + /* The size of the row must be within the limits of this architecture. + * Because the read code can perform arbitrary transformations the + * maximum size is checked here. Because the code in png_read_start_row + * adds extra space "for safety's sake" in several places a conservative + * limit is used here. + * + * NOTE: it would be far better to check the size that is actually used, + * but the effect in the real world is minor and the changes are more + * extensive, therefore much more dangerous and much more difficult to + * write in a way that avoids compiler warnings. + */ + png_warning(png_ptr, "Image width is too large for this architecture"); error = 1; } @@ -801,6 +834,18 @@ png_check_IHDR(png_structp png_ptr, error = 1; } + if (height == 0) + { + png_warning(png_ptr, "Image height is zero in IHDR"); + error = 1; + } + + if (height > PNG_UINT_31_MAX) + { + png_warning(png_ptr, "Invalid image height in IHDR"); + error = 1; + } + #ifdef PNG_SET_USER_LIMITS_SUPPORTED if (height > png_ptr->user_height_max || height > PNG_USER_HEIGHT_MAX) #else @@ -811,18 +856,6 @@ png_check_IHDR(png_structp png_ptr, error = 1; } - if (width > PNG_UINT_31_MAX) - { - png_warning(png_ptr, "Invalid image width in IHDR"); - error = 1; - } - - if ( height > PNG_UINT_31_MAX) - { - png_warning(png_ptr, "Invalid image height in IHDR"); - error = 1; - } - /* Check other values */ if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 && bit_depth != 8 && bit_depth != 16)