[libpng16] Added overflow detection in png_set_sPLT() and png_set_text_2().
diff --git a/ANNOUNCE b/ANNOUNCE
index bc2b2dc..1b9014b 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,5 +1,5 @@
-Libpng 1.6.0beta39 - January 17, 2013
+Libpng 1.6.0beta39 - January 19, 2013
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.
@@ -587,10 +587,9 @@
Fixed conceivable but difficult to repro overflow. Also added two test
programs to generate and test a PNG which should have the problem.
-Version 1.6.0beta38 [January 17, 2013]
- Corrected previous attempt at overflow detection in png_set_unknown_chunks().
-
-Version 1.6.0beta39 [January 17, 2013]
+Version 1.6.0beta39 [January 19, 2013]
+ Again corrected attempt at overflow detection in png_set_unknown_chunks().
+ Added overflow detection in png_set_sPLT() and png_set_text_2().
===========================================================================
NOTICE November 17, 2012:
diff --git a/CHANGES b/CHANGES
index 7b08e47..3b25bd2 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4340,10 +4340,9 @@
Fixed conceivable but difficult to repro overflow. Also added two test
programs to generate and test a PNG which should have the problem.
-Version 1.6.0beta38 [January 17, 2013]
- Corrected previous attempt at overflow detection in png_set_unknown_chunks().
-
-Version 1.6.0beta39 [January 17, 2013]
+Version 1.6.0beta39 [January 19, 2013]
+ Again corrected attempt at overflow detection in png_set_unknown_chunks().
+ Added overflow detection in png_set_sPLT() and png_set_text_2().
===========================================================================
NOTICE November 17, 2012:
diff --git a/pngset.c b/pngset.c
index 47d5307..61232bf 100644
--- a/pngset.c
+++ b/pngset.c
@@ -701,7 +701,22 @@
/* Make sure we have enough space in the "text" array in info_struct
* to hold all of the incoming text_ptr objects.
+ *
+ * There were two overflow conditions here, one on the count and one on
+ * memory. On a 32-bit system the memory limit is critical, while on a
+ * 64-bit system the count limit is critical. This test defends against
+ * both.
*/
+ if (num_text < 0 ||
+ num_text > INT_MAX - info_ptr->num_text - 8 ||
+ (unsigned int)/*SAFE*/(num_text +/*SAFE*/
+ info_ptr->num_text + 8) >=
+ PNG_SIZE_MAX/(sizeof (png_text)))
+ {
+ png_warning(png_ptr, "too many text chunks");
+ return(0);
+ }
+
if (info_ptr->num_text + num_text > info_ptr->max_text)
{
int old_max_text = info_ptr->max_text;
@@ -980,8 +995,16 @@
entries == NULL)
return;
- np = png_voidcast(png_sPLT_tp, png_malloc_warn(png_ptr,
- (info_ptr->splt_palettes_num + nentries) * (sizeof (png_sPLT_t))));
+ /* See explanation of this in png_set_text_2(). */
+ if (nentries < 0 ||
+ nentries > INT_MAX-info_ptr->splt_palettes_num ||
+ (unsigned int)(nentries + info_ptr->splt_palettes_num) >=
+ PNG_SIZE_MAX/(sizeof (png_sPLT_t)))
+ np=NULL;
+
+ else
+ np = png_voidcast(png_sPLT_tp, png_malloc_warn(png_ptr,
+ (info_ptr->splt_palettes_num + nentries) * (sizeof (png_sPLT_t))));
if (np == NULL)
{
@@ -1086,12 +1109,11 @@
void PNGAPI
png_set_unknown_chunks(png_const_structrp png_ptr,
- png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns_in)
+ png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)
{
- png_uint_32 num_unknowns;
png_unknown_chunkp np;
- if (png_ptr == NULL || info_ptr == NULL || num_unknowns_in <= 0)
+ if (png_ptr == NULL || info_ptr == NULL || num_unknowns <= 0)
return;
/* Check for the failure cases where support has been disabled at compile
@@ -1117,33 +1139,32 @@
}
# endif
- /* Prior to 1.6.0 this code used png_malloc_warn, however this meant that
- * unknown critical chunks could be lost with just a warning resulting in
- * undefined behavior. Changing to png_malloc fixes this by producing a
- * png_error. The (png_size_t) cast was also removed as it hides a potential
- * overflow.
- */
- num_unknowns = (unsigned int)/*SAFE*/num_unknowns_in;
+ /* See the comments in png_set_text_2(). */
+ if (num_unknowns < 0 ||
+ num_unknowns > INT_MAX-info_ptr->unknown_chunks_num ||
+ (unsigned int)(num_unknowns +
+ info_ptr->unknown_chunks_num) >=
+ PNG_SIZE_MAX/(sizeof (png_unknown_chunk)))
+ np=NULL;
- /* There are two overflow conditions, one on the count one on memory, on a
- * 32-bit system the memory limit is critical, on a 64-bit system the count
- * limit.
- */
- if (num_unknowns > PNG_UINT_32_MAX - info_ptr->unknown_chunks_num ||
- num_unknowns + info_ptr->unknown_chunks_num > PNG_SIZE_MAX/(sizeof *np))
- {
- /* This is a benign read error (user limits are disabled and we are about
- * to overflow 2^32 chunks) and an application write error.
+ else
+ /* Prior to 1.6.0 this code used png_malloc_warn; however, this meant that
+ * unknown critical chunks could be lost with just a warning resulting in
+ * undefined behavior. Changing to png_malloc fixes this by producing a
+ * png_error. The (png_size_t) cast was also removed as it hides a
+ * potential overflow.
*/
- png_chunk_report(png_ptr, "too many unknown chunks",
- PNG_CHUNK_WRITE_ERROR);
+ np = png_voidcast(png_unknown_chunkp, png_malloc(png_ptr,
+ (info_ptr->unknown_chunks_num + num_unknowns) *
+ (sizeof (png_unknown_chunk))));
+
+ if (np == NULL)
+ {
+ png_warning(png_ptr,
+ "Out of memory while processing unknown chunk");
return;
}
- np = png_voidcast(png_unknown_chunkp, png_malloc(png_ptr,
- (info_ptr->unknown_chunks_num + num_unknowns) *
- (sizeof (png_unknown_chunk))));
-
memcpy(np, info_ptr->unknown_chunks,
info_ptr->unknown_chunks_num * (sizeof (png_unknown_chunk)));
@@ -1515,7 +1536,7 @@
png_set_chunk_cache_max (png_structrp png_ptr, png_uint_32 user_chunk_cache_max)
{
if (png_ptr)
- png_ptr->user_chunk_cache_max = user_chunk_cache_max;
+ png_ptr->user_chunk_cache_max = (int) user_chunk_cache_max;
}
/* This function was added to libpng 1.4.1 */