Patrick Williams | f1e5d69 | 2016-03-30 15:21:19 -0500 | [diff] [blame] | 1 | From a901eb3ce6087e0afeef988247f1a1aa208cb54d Mon Sep 17 00:00:00 2001 |
| 2 | From: Glenn Randers-Pehrson <glennrp at users.sourceforge.net> |
| 3 | Date: Fri, 30 Oct 2015 07:57:49 -0500 |
| 4 | Subject: [PATCH] [libpng16] Prevent reading over-length PLTE chunk (Cosmin |
| 5 | Truta). |
| 6 | |
| 7 | Upstream-Status: Backport |
| 8 | https://github.com/glennrp/libpng/commit/a901eb3ce6087e0afeef988247f1a1aa208cb54d |
| 9 | |
| 10 | Many changes involved date and version updates with don't apply in this case. |
| 11 | |
| 12 | CVE: CVE-2015-8126 patch #2 |
| 13 | Signed-off-by: Armin Kuster <akuster@mvista.com> |
| 14 | |
| 15 | --- |
| 16 | ANNOUNCE | 6 +++--- |
| 17 | CHANGES | 4 ++-- |
| 18 | libpng-manual.txt | 11 +++++------ |
| 19 | libpng.3 | 19 +++++++++---------- |
| 20 | pngrutil.c | 3 +++ |
| 21 | pngset.c | 13 +++++++++---- |
| 22 | pngwutil.c | 6 +++--- |
| 23 | 7 files changed, 34 insertions(+), 28 deletions(-) |
| 24 | |
| 25 | Index: libpng-1.6.17/libpng-manual.txt |
| 26 | =================================================================== |
| 27 | --- libpng-1.6.17.orig/libpng-manual.txt |
| 28 | +++ libpng-1.6.17/libpng-manual.txt |
| 29 | @@ -5109,10 +5109,9 @@ length, which resulted in PNG files that |
| 30 | chunk. This error was fixed in libpng-1.6.3, and a tool (called |
| 31 | contrib/tools/png-fix-itxt) has been added to the libpng distribution. |
| 32 | |
| 33 | -Starting with libpng-1.6.19, attempting to write an over-length PLTE chunk |
| 34 | +Starting with libpng-1.6.19, attempting to set an over-length PLTE chunk |
| 35 | is an error. Previously this requirement of the PNG specification was not |
| 36 | -enforced. Libpng continues to accept over-length PLTE chunks when reading, |
| 37 | -but does not make any use of the extra entries. |
| 38 | +enforced, and the palette was always limited to 256 entries. |
| 39 | |
| 40 | XIII. Detecting libpng |
| 41 | |
| 42 | Index: libpng-1.6.17/libpng.3 |
| 43 | =================================================================== |
| 44 | --- libpng-1.6.17.orig/libpng.3 |
| 45 | +++ libpng-1.6.17/libpng.3 |
| 46 | @@ -5613,10 +5613,9 @@ length, which resulted in PNG files that |
| 47 | chunk. This error was fixed in libpng-1.6.3, and a tool (called |
| 48 | contrib/tools/png-fix-itxt) has been added to the libpng distribution. |
| 49 | |
| 50 | -Starting with libpng-1.6.19, attempting to write an over-length PLTE chunk |
| 51 | +Starting with libpng-1.6.19, attempting to set an over-length PLTE chunk |
| 52 | is an error. Previously this requirement of the PNG specification was not |
| 53 | -enforced. Libpng continues to accept over-length PLTE chunks when reading, |
| 54 | -but does not make any use of the extra entries. |
| 55 | +enforced, and the palette was always limited to 256 entries. |
| 56 | |
| 57 | .SH XIII. Detecting libpng |
| 58 | |
| 59 | Index: libpng-1.6.17/pngrutil.c |
| 60 | =================================================================== |
| 61 | --- libpng-1.6.17.orig/pngrutil.c |
| 62 | +++ libpng-1.6.17/pngrutil.c |
| 63 | @@ -997,6 +997,9 @@ png_handle_PLTE(png_structrp png_ptr, pn |
| 64 | * confusing. |
| 65 | * |
| 66 | * Fix this by not sharing the palette in this way. |
| 67 | + * |
| 68 | + * Starting with libpng-1.6.19, png_set_PLTE() also issues a png_error() when |
| 69 | + * it attempts to set a palette length that is too large for the bit depth. |
| 70 | */ |
| 71 | png_set_PLTE(png_ptr, info_ptr, palette, num); |
| 72 | |
| 73 | Index: libpng-1.6.17/pngset.c |
| 74 | =================================================================== |
| 75 | --- libpng-1.6.17.orig/pngset.c |
| 76 | +++ libpng-1.6.17/pngset.c |
| 77 | @@ -513,12 +513,17 @@ png_set_PLTE(png_structrp png_ptr, png_i |
| 78 | png_const_colorp palette, int num_palette) |
| 79 | { |
| 80 | |
| 81 | + png_uint_32 max_palette_length; |
| 82 | + |
| 83 | png_debug1(1, "in %s storage function", "PLTE"); |
| 84 | |
| 85 | if (png_ptr == NULL || info_ptr == NULL) |
| 86 | return; |
| 87 | |
| 88 | - if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH) |
| 89 | + max_palette_length = (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ? |
| 90 | + (1 << png_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH; |
| 91 | + |
| 92 | + if (num_palette < 0 || num_palette > max_palette_length) |
| 93 | { |
| 94 | if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) |
| 95 | png_error(png_ptr, "Invalid palette length"); |
| 96 | @@ -551,8 +556,8 @@ png_set_PLTE(png_structrp png_ptr, png_i |
| 97 | png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0); |
| 98 | |
| 99 | /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead |
| 100 | - * of num_palette entries, in case of an invalid PNG file that has |
| 101 | - * too-large sample values. |
| 102 | + * of num_palette entries, in case of an invalid PNG file or incorrect |
| 103 | + * call to png_set_PLTE() with too-large sample values. |
| 104 | */ |
| 105 | png_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr, |
| 106 | PNG_MAX_PALETTE_LENGTH * (sizeof (png_color)))); |
| 107 | Index: libpng-1.6.17/pngwutil.c |
| 108 | =================================================================== |
| 109 | --- libpng-1.6.17.orig/pngwutil.c |
| 110 | +++ libpng-1.6.17/pngwutil.c |
| 111 | @@ -922,20 +922,20 @@ void /* PRIVATE */ |
| 112 | png_write_PLTE(png_structrp png_ptr, png_const_colorp palette, |
| 113 | png_uint_32 num_pal) |
| 114 | { |
| 115 | - png_uint_32 max_num_pal, i; |
| 116 | + png_uint_32 max_palette_length, i; |
| 117 | png_const_colorp pal_ptr; |
| 118 | png_byte buf[3]; |
| 119 | |
| 120 | png_debug(1, "in png_write_PLTE"); |
| 121 | |
| 122 | - max_num_pal = (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ? |
| 123 | + max_palette_length = (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ? |
| 124 | (1 << png_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH; |
| 125 | |
| 126 | if (( |
| 127 | #ifdef PNG_MNG_FEATURES_SUPPORTED |
| 128 | (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0 && |
| 129 | #endif |
| 130 | - num_pal == 0) || num_pal > max_num_pal) |
| 131 | + num_pal == 0) || num_pal > max_palette_length) |
| 132 | { |
| 133 | if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) |
| 134 | { |