From a901eb3ce6087e0afeef988247f1a1aa208cb54d Mon Sep 17 00:00:00 2001 From: Glenn Randers-Pehrson Date: Fri, 30 Oct 2015 07:57:49 -0500 Subject: [PATCH] [libpng16] Prevent reading over-length PLTE chunk (Cosmin Truta). Upstream-Status: Backport https://github.com/glennrp/libpng/commit/a901eb3ce6087e0afeef988247f1a1aa208cb54d Many changes involved date and version updates with don't apply in this case. CVE: CVE-2015-8126 patch #2 Signed-off-by: Armin Kuster Signed-off-by: Sona Sarmadi diff -ruN a/pngrutil.c b/pngrutil.c --- a/pngrutil.c 2014-08-21 12:53:36.000000000 +0200 +++ b/pngrutil.c 2016-03-14 13:05:12.419581068 +0100 @@ -997,6 +997,9 @@ * confusing. * * Fix this by not sharing the palette in this way. + * + * Starting with libpng-1.6.19, png_set_PLTE() also issues a png_error() when + * it attempts to set a palette length that is too large for the bit depth. */ png_set_PLTE(png_ptr, info_ptr, palette, num); diff -ruN a/pngset.c b/pngset.c --- a/pngset.c 2014-08-21 12:53:36.000000000 +0200 +++ b/pngset.c 2016-03-14 13:05:12.439580208 +0100 @@ -503,12 +503,17 @@ png_const_colorp palette, int num_palette) { + png_uint_32 max_palette_length; + png_debug1(1, "in %s storage function", "PLTE"); if (png_ptr == NULL || info_ptr == NULL) 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 > max_palette_length) { if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) png_error(png_ptr, "Invalid palette length"); @@ -541,8 +546,8 @@ png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0); /* 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 - * too-large sample values. + * of num_palette entries, in case of an invalid PNG file or incorrect + * call to png_set_PLTE() with too-large sample values. */ png_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr, PNG_MAX_PALETTE_LENGTH * (sizeof (png_color)))); diff -ruN a/pngwutil.c b/pngwutil.c --- a/pngwutil.c 2016-03-14 13:01:23.433428517 +0100 +++ b/pngwutil.c 2016-03-14 13:07:42.933108329 +0100 @@ -919,20 +919,20 @@ png_write_PLTE(png_structrp png_ptr, png_const_colorp palette, png_uint_32 num_pal) { - png_uint_32 max_num_pal, i; + png_uint_32 max_palette_length, i; png_const_colorp pal_ptr; png_byte buf[3]; png_debug(1, "in png_write_PLTE"); - max_num_pal = (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ? + max_palette_length = (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ? (1 << png_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH; if (( #ifdef PNG_MNG_FEATURES_SUPPORTED !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) && #endif - num_pal == 0) || num_pal > max_num_pal) + num_pal == 0) || num_pal > max_palette_length) { if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) {