Hi,
I find a out of bound read bug in libpng 1.2.-1.2.53 and libpng 1.4..
the details as follows:( in function png_convert_to_rfc1123 in png.c)
514 png_charp PNGAPI
515 png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime)
516 {
517 static PNG_CONST char short_months[12][4] =
518 {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
519 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
...
540 png_snprintf6(png_ptr->time_buffer, 29, "%d %s %d %02d:%02d:%02d +0000"
541 ptime->day % 32, short_months[(ptime->month - 1) % 12],
542 ptime->year, ptime->hour % 24, ptime->minute % 60,
543 ptime->second % 61);
...
when ptime->month is 0 (which gains from tIME chunk data ), the short_months[(ptime->month - 1) % 12] will return the memory before short_months. and a out of bound memory read occurs.
this bug exsit in 1.2. and 1.4. , and is not in 1.6.*
Thanks. We'll take care of the bug by using "ptime->month - 1U" to ensure that the "%" operation returns a value in the range 0..11, and backport the check in png_set_tIME() from libpng15 to libpng14, libpng12, and libpng10. Do you wish to reveal your real name in the CHANGES file? Otherwise I'll credit "anonymous bug reporter".
My name is "Qixue Xiao", and It is a pleasure to contribute to LIBPNG.
This is fixed in the latest libpng12 and libpng14 betas.
This has now been assigned CVE-2015-7981.
I've made a test PNG with a tIME chunk containing just 7 0 bytes.
Nothing interesting happens when I read it with pngtest or
imagemagick built with an unpatched libpng12. Both read the
file without complaining, and omit the erroneous tIME chunk
when writing. I suppose an ASAN build or a valgrind run would
notice the read of 4 bytes preceding the static "short_months"
array.
Here's the "pngtest" output:
libpng version 1.2.50 - July 10, 2012
Copyright (c) 1998-2011 Glenn Randers-Pehrson
Copyright (c) 1996-1997 Andreas Dilger
Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
library (10250): libpng version 1.2.50 - July 10, 2012
pngtest (10250): libpng version 1.2.50 - July 10, 2012
sizeof(png_struct)=1256, sizeof(png_info)=464
libpng warning: Invalid time specified for tIME chunk
Testing tIMEzero.png:
Pass 0: rw
Image width = 1, height = 1
Files tIMEzero.png and pngout.png are different
Was tIMEzero.png written with the same maximum IDAT chunk size (8192 bytes),
filtering heuristic (libpng default), compression level (zlib default),
and zlib version (1.2.7)?
PASS (2 zero samples)
Filter 0 was used 1 times
tIME = 0 0 00:00:00 +0000
libpng passes test
Compare to the final 2 lines of running pngtest against the libpng-supplied pngtest.png:
tIME = 7 Jun 1996 17:58:08 +0000
libpng passes test
Note that only applications that call png_convert_to_rfc1123() are vulnerable.
Last edit: Glenn Randers-Pehrson 2015-10-27
The png_convert_to_rfc1123 code looks the same in libpng 1.0.63; should there be an update for libpng10 too?
Yes, there will be a libpng-1.0.64 release on November 5th. libpng10 is built from the same source as libpng12 so no need for beta and rc releases of libpng10.
Fixed in libpng-1.0.64, 1.2.54, 1.4.17, and 1.5.24; thanks for the report.