summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn Randers-Pehrson <glennrp at users.sourceforge.net>2017-08-06 20:32:11 -0500
committerGlenn Randers-Pehrson <glennrp at users.sourceforge.net>2017-08-06 20:32:11 -0500
commit1a74f4f5f9f7f85e2ddb2d160d1aca15b10f7aa3 (patch)
treea4523635dac5b62348c159d844a0d0acf236736f
parent03f35f7156be2de65af83d86e07c1d08f041942d (diff)
downloadlibpng-1a74f4f5f9f7f85e2ddb2d160d1aca15b10f7aa3.tar.gz
[lbpng14] Moved chunk-name and chunk-length checks into PNG_EXTERN private
png_check_chunk_name() and png_check_chunk_length() functions (Suggested by Max Stepin).
-rw-r--r--ANNOUNCE5
-rw-r--r--CHANGES7
-rw-r--r--pngpread.c1
-rw-r--r--pngpriv.h2
-rw-r--r--pngrutil.c89
5 files changed, 82 insertions, 22 deletions
diff --git a/ANNOUNCE b/ANNOUNCE
index 5b9e0a6cf..3d9f4c897 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,5 +1,5 @@
-Libpng 1.4.21beta01 - December 30, 2016
+Libpng 1.4.21beta01 - August 7, 2017
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.
@@ -27,6 +27,9 @@ Other information:
Changes since the last public release (1.4.20):
version 1.4.21 [%RDATE%]
+ Moved chunk-name and chunk-length checks into PNG_EXTERN private
+ png_check_chunk_name() and png_check_chunk_length() functions
+ (Suggested by Max Stepin).
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 f1a1ec51b..1a7a2b750 100644
--- a/CHANGES
+++ b/CHANGES
@@ -3041,9 +3041,12 @@ version 1.4.20rc01 [December 27, 2016]
version 1.4.20 [December 29, 2016]
Fixed a potential null pointer dereference in png_set_text_2() (bug report
- and patch by Patrick Keshishian).
+ and patch by Patrick Keshishian, CVE-2016-10087).
-version 1.4.21 [December 30, 2016]
+version 1.4.21 [August 7, 2017]
+ Moved chunk-name and chunk-length checks into PNG_EXTERN private
+ png_check_chunk_name() and png_check_chunk_length() functions
+ (Suggested by Max Stepin).
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/pngpread.c b/pngpread.c
index d8e9104c1..4c844e916 100644
--- a/pngpread.c
+++ b/pngpread.c
@@ -203,6 +203,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
png_reset_crc(png_ptr);
png_crc_read(png_ptr, png_ptr->chunk_name, 4);
png_check_chunk_name(png_ptr, png_ptr->chunk_name);
+ png_check_chunk_length(png_ptr, png_ptr->push_length);
png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
}
diff --git a/pngpriv.h b/pngpriv.h
index 4e990f9a5..150a4fa4b 100644
--- a/pngpriv.h
+++ b/pngpriv.h
@@ -1,7 +1,7 @@
/* pngpriv.h - private declarations for use inside libpng
*
- * libpng version 1.4.21beta01 - December 30, 2016
+ * libpng version 1.4.20 - December 29, 2016
* For conditions of distribution and use, see copyright notice in png.h
* Copyright (c) 1998-2002,2004,2006-2014 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
diff --git a/pngrutil.c b/pngrutil.c
index 26ba00ee3..98ad5115e 100644
--- a/pngrutil.c
+++ b/pngrutil.c
@@ -119,6 +119,74 @@ png_read_sig(png_structp png_ptr, png_infop info_ptr)
png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
}
+/* This function is called to verify that a chunk name is valid.
+ This function can't have the "critical chunk check" incorporated
+ into it, since in the future we will need to be able to call user
+ functions to handle unknown critical chunks after we check that
+ the chunk name itself is valid. */
+
+/* Bit hacking: the test for an invalid byte in the 4 byte chunk name is:
+ *
+ * ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
+ */
+
+void /* PRIVATE */
+png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
+{
+ int i;
+ png_uint_32 cn=chunk_name[0]<<24|chunk_name[1]<<16|chunk_name[2]<<8|
+ chunk_name[3];
+
+ png_debug(1, "in png_check_chunk_name");
+
+ for (i=1; i<=4; ++i)
+ {
+ int c = cn & 0xff;
+
+ if (c < 65 || c > 122 || (c > 90 && c < 97))
+ png_chunk_error(png_ptr, "invalid chunk type");
+
+ cn >>= 8;
+ }
+}
+
+void /* PRIVATE */
+png_check_chunk_length(png_structp png_ptr, png_uint_32 length)
+{
+ png_uint_32 limit = PNG_UINT_31_MAX;
+
+ /* if (png_ptr->chunk_name != "IDAT") */
+ if (png_ptr->chunk_name[0] != 73 || png_ptr->chunk_name[1] !=68 ||
+ png_ptr->chunk_name[2] != 65 || png_ptr->chunk_name[3] !=84)
+ {
+# ifdef PNG_SET_USER_LIMITS_SUPPORTED
+ if (png_ptr->user_chunk_malloc_max > 0 &&
+ png_ptr->user_chunk_malloc_max < limit)
+ limit = png_ptr->user_chunk_malloc_max;
+# elif PNG_USER_CHUNK_MALLOC_MAX > 0
+ if (PNG_USER_CHUNK_MALLOC_MAX < limit)
+ limit = PNG_USER_CHUNK_MALLOC_MAX;
+# endif
+ }
+ else
+ {
+ size_t row_factor =
+ (png_ptr->width * png_ptr->channels * (png_ptr->bit_depth > 8? 2: 1)
+ + 1 + (png_ptr->interlaced? 6: 0));
+ if (png_ptr->height > PNG_UINT_32_MAX/row_factor)
+ limit=PNG_UINT_31_MAX;
+ else
+ limit = png_ptr->height * row_factor;
+ limit += 6 + 5*(limit/32566+1); /* zlib+deflate overhead */
+ limit=limit < PNG_UINT_31_MAX? limit : PNG_UINT_31_MAX;
+ }
+ if (length > limit)
+ {
+ png_debug2(0," length = %lu, limit = %lu",
+ (unsigned long)length,(unsigned long)limit);
+ png_chunk_error(png_ptr, "chunk data is too large");
+ }
+}
/* Read the chunk header (length + type name).
* Put the type name into png_ptr->chunk_name, and return the length.
*/
@@ -151,6 +219,9 @@ png_read_chunk_header(png_structp png_ptr)
/* Check to see if chunk name is valid. */
png_check_chunk_name(png_ptr, png_ptr->chunk_name);
+ /* Check for too-large chunk length */
+ png_check_chunk_length(png_ptr, length);
+
#ifdef PNG_IO_STATE_SUPPORTED
/* It is unspecified how many I/O calls will be performed
* during the serialization of the chunk data.
@@ -2535,24 +2606,6 @@ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
#endif
}
-/* This function is called to verify that a chunk name is valid.
- This function can't have the "critical chunk check" incorporated
- into it, since in the future we will need to be able to call user
- functions to handle unknown critical chunks after we check that
- the chunk name itself is valid. */
-
-#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
-
-void /* PRIVATE */
-png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
-{
- png_debug(1, "in png_check_chunk_name");
- if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
- isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
- {
- png_chunk_error(png_ptr, "invalid chunk type");
- }
-}
/* Combines the row recently read in with the existing pixels in the
row. This routine takes care of alpha and transparency if requested.