[libpng17] Prevent setting or writing over-length PLTE chunk (Cosmin Truta).

Silently truncate over-length PLTE chunk while reading.
This commit is contained in:
Glenn Randers-Pehrson 2015-11-01 13:01:56 -06:00
parent 5b05197604
commit 9f7d5aa973
5 changed files with 42 additions and 17 deletions

View File

@ -1,5 +1,5 @@
Libpng 1.7.0beta67 - October 10, 2015 Libpng 1.7.0beta67 - November 1, 2015
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.
@ -944,13 +944,15 @@ Version 1.7.0beta66 [October 2, 2015]
extended sBIT handling to the colormap code in the simplified API extended sBIT handling to the colormap code in the simplified API
which is separately implemented in pngread.c (John Bowler). which is separately implemented in pngread.c (John Bowler).
Version 1.7.0beta67 [October 10, 2015] Version 1.7.0beta67 [November 1, 2015]
Fixed 'pow' macros in pngvalid.c. It is legal for 'pow' to be a Fixed 'pow' macros in pngvalid.c. It is legal for 'pow' to be a
macro, therefore the argument list cannot contain preprocessing macro, therefore the argument list cannot contain preprocessing
directives. Make sure pow is a function where this happens. This is directives. Make sure pow is a function where this happens. This is
a minimal safe fix, the issue only arises in non-performance-critical a minimal safe fix, the issue only arises in non-performance-critical
code (bug report by Curtis Leach, fix by John Bowler). code (bug report by Curtis Leach, fix by John Bowler).
Added sPLT chunk support to pngtest.c Added sPLT chunk support to pngtest.c
Prevent setting or writing over-length PLTE chunk (Cosmin Truta).
Silently truncate over-length PLTE chunk while reading.
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

@ -3754,7 +3754,8 @@ Version 1.5.7beta04 [November 17, 2011]
Version 1.5.7beta05 [November 25, 2011] Version 1.5.7beta05 [November 25, 2011]
Removed "zTXt" from warning in generic chunk decompression function. Removed "zTXt" from warning in generic chunk decompression function.
Validate time settings passed to pngset() and png_convert_to_rfc1123() Validate time settings passed to pngset() and png_convert_to_rfc1123()
(Frank Busse). (Frank Busse). Note: This prevented CVE-2015-7981 from affecting
libpng-1.5.7 and later.
Added MINGW support to CMakeLists.txt Added MINGW support to CMakeLists.txt
Reject invalid compression flag or method when reading the iTXt chunk. Reject invalid compression flag or method when reading the iTXt chunk.
Backed out 'simplified' API changes. The API seems too complex and there Backed out 'simplified' API changes. The API seems too complex and there
@ -5243,13 +5244,15 @@ Version 1.7.0beta66 [October 2, 2015]
extended sBIT handling to the colormap code in the simplified API extended sBIT handling to the colormap code in the simplified API
which is separately implemented in pngread.c (John Bowler). which is separately implemented in pngread.c (John Bowler).
Version 1.7.0beta67 [October 10, 2015] Version 1.7.0beta67 [November 1, 2015]
Fixed 'pow' macros in pngvalid.c. It is legal for 'pow' to be a Fixed 'pow' macros in pngvalid.c. It is legal for 'pow' to be a
macro, therefore the argument list cannot contain preprocessing macro, therefore the argument list cannot contain preprocessing
directives. Make sure pow is a function where this happens. This is directives. Make sure pow is a function where this happens. This is
a minimal safe fix, the issue only arises in non-performance-critical a minimal safe fix, the issue only arises in non-performance-critical
code (bug report by Curtis Leach, fix by John Bowler). code (bug report by Curtis Leach, fix by John Bowler).
Added sPLT chunk support to pngtest.c Added sPLT chunk support to pngtest.c
Prevent setting or writing over-length PLTE chunk (Cosmin Truta).
Silently truncate over-length PLTE chunk while reading.
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

@ -849,7 +849,7 @@ png_handle_PLTE(png_structrp png_ptr, png_inforp info_ptr)
{ {
png_color palette[PNG_MAX_PALETTE_LENGTH]; png_color palette[PNG_MAX_PALETTE_LENGTH];
png_uint_32 length = png_ptr->chunk_length; png_uint_32 length = png_ptr->chunk_length;
int num, i; int max_palette_length, num, i;
png_colorp pal_ptr; png_colorp pal_ptr;
png_debug(1, "in png_handle_PLTE"); png_debug(1, "in png_handle_PLTE");
@ -868,6 +868,10 @@ png_handle_PLTE(png_structrp png_ptr, png_inforp info_ptr)
} }
#endif #endif
max_palette_length = (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?
(1 << png_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH;
if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3) if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
{ {
png_crc_finish(png_ptr, length); png_crc_finish(png_ptr, length);
@ -878,7 +882,15 @@ png_handle_PLTE(png_structrp png_ptr, png_inforp info_ptr)
} }
/* The cast is safe because 'length' is less than 3*PNG_MAX_PALETTE_LENGTH */ /* The cast is safe because 'length' is less than 3*PNG_MAX_PALETTE_LENGTH */
num = (int)/*SAFE*/length / 3; num = (int)length / 3;
/* If the palette has 256 or fewer entries but is too large for the bit
* depth, we don't issue an error, to preserve the behavior of previous
* libpng versions. We silently truncate the unused extra palette entries
* here.
*/
if (num > max_palette_length)
num = max_palette_length;
for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++) for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
{ {

View File

@ -124,12 +124,12 @@ png_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp info_ptr, double red_X,
png_fixed(png_ptr, red_X, "cHRM Red X"), png_fixed(png_ptr, red_X, "cHRM Red X"),
png_fixed(png_ptr, red_Y, "cHRM Red Y"), png_fixed(png_ptr, red_Y, "cHRM Red Y"),
png_fixed(png_ptr, red_Z, "cHRM Red Z"), png_fixed(png_ptr, red_Z, "cHRM Red Z"),
png_fixed(png_ptr, green_X, "cHRM Red X"), png_fixed(png_ptr, green_X, "cHRM Green X"),
png_fixed(png_ptr, green_Y, "cHRM Red Y"), png_fixed(png_ptr, green_Y, "cHRM Green Y"),
png_fixed(png_ptr, green_Z, "cHRM Red Z"), png_fixed(png_ptr, green_Z, "cHRM Green Z"),
png_fixed(png_ptr, blue_X, "cHRM Red X"), png_fixed(png_ptr, blue_X, "cHRM Blue X"),
png_fixed(png_ptr, blue_Y, "cHRM Red Y"), png_fixed(png_ptr, blue_Y, "cHRM Blue Y"),
png_fixed(png_ptr, blue_Z, "cHRM Red Z")); png_fixed(png_ptr, blue_Z, "cHRM Blue Z"));
} }
# endif /* FLOATING_POINT */ # endif /* FLOATING_POINT */
@ -502,12 +502,17 @@ png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr,
png_const_colorp palette, int num_palette) png_const_colorp palette, int num_palette)
{ {
png_uint_32 max_palette_length;
png_debug1(1, "in %s storage function", "PLTE"); png_debug1(1, "in %s storage function", "PLTE");
if (png_ptr == NULL || info_ptr == NULL) if (png_ptr == NULL || info_ptr == NULL)
return; return;
if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH) max_palette_length = (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?
(1 << png_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH;
if (num_palette < 0 || num_palette > (int) max_palette_length)
{ {
if ((info_ptr->format == PNG_FORMAT_FLAG_COLORMAP) != 0) if ((info_ptr->format == PNG_FORMAT_FLAG_COLORMAP) != 0)
png_chunk_error(png_ptr, "Invalid palette length"); png_chunk_error(png_ptr, "Invalid palette length");
@ -537,8 +542,8 @@ png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr,
png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0); png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
/* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead
* of num_palette entries, in case of an invalid PNG file that has * of num_palette entries, in case of an invalid PNG file or incorrect
* too-large sample values. * call to png_set_PLTE() with too-large sample values.
*/ */
png_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr, png_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr,
PNG_MAX_PALETTE_LENGTH * (sizeof (png_color)))); PNG_MAX_PALETTE_LENGTH * (sizeof (png_color))));

View File

@ -911,17 +911,20 @@ void /* PRIVATE */
png_write_PLTE(png_structrp png_ptr, png_const_colorp palette, png_write_PLTE(png_structrp png_ptr, png_const_colorp palette,
unsigned int num_pal) unsigned int num_pal)
{ {
png_uint_32 i; png_uint_32 max_palette_length, i;
png_const_colorp pal_ptr; png_const_colorp pal_ptr;
png_byte buf[3]; png_byte buf[3];
png_debug(1, "in png_write_PLTE"); png_debug(1, "in png_write_PLTE");
max_palette_length = (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?
(1 << png_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH;
if (( if ((
# ifdef PNG_MNG_FEATURES_SUPPORTED # ifdef PNG_MNG_FEATURES_SUPPORTED
(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0 && (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0 &&
# endif /* MNG_FEATURES */ # endif /* MNG_FEATURES */
num_pal == 0) || num_pal > PNG_MAX_PALETTE_LENGTH) num_pal == 0) || num_pal > max_palette_length)
{ {
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
{ {