SECURITY ADVISORY about libpng-1.2.5 and earlier versions
                   Revision 004 9 August 2004


                      COPYRIGHT and LICENSE

Copyright 2004, Glenn Randers-Pehrson <glennrp at users.sourceforge.net>

This document and these patches are distributed according to the same
terms and conditions as libpng itself, as described in png.h.



                          INTRODUCTION


Here are the CVE names and CERT vulnerability numbers for the vulnerabilities
that have been disclosed for libpng-1.2.5:

  CAN-2002-1363:

    Buffer overrun while adding filler bytes to 16-bit RGBA samples.

  CAN-2004-0768:

    Buffer overrun while adding filler bytes to 16-bit grayscale samples.

  CAN-2004-0597:

    CERT VU#388984: Remotely exploitable stack-based buffer overrun
       in png_handle_tRNS (pngrutil.c)

    CERT VU#817368: Dangerous code in png_handle_sBIT (pngrutil.c)
       (Similar code in png_handle_hIST).

  CAN-2004-0598:

    CERT VU#236656: Possible NULL-pointer crash in png_handle_iCCP
       (pngrutil.c) (this flaw is duplicated in multiple other locations).

  CAN-2004-0599:

    CERT VU#477512: Theoretical integer overflow in allocation in
       png_handle_sPLT (pngrutil.c)

    CERT VU#160448: Integer overflow in png_read_png (pngread.c)

    CERT VU#286464: Integer overflows during progressive reading.



This directory contains a set of patches for these libpng vulnerabilities.
This document, plus the patches and new libpng-1.2.6rc2 distribution,
constitute the PNG Development Group's "vendor response" to the
vulnerability reports.

The worst of the vulnerabilities is a buffer overflow that can
occur while reading the tRNS chunk, which is Item 1 of CAN-2004-0597.
To defend against this, you can patch libpng using the appropriate
one of libpng-patch-03, 03a, or 03b listed below, and/or use the
warning_callback method described in "Patching applications that
use libpng", below.



      PATCHING LIBPNG FOR INDIVIDUAL VULNERABILITIES


Here are individual patches for each vulnerability, if you want
to pick and choose which ones to fix (if you prefer to patch
your entire library with a single combined patch, see 
the section entitled "PATCHING LIBPNG LIBRARIES", below):

   libpng-patch00-pngrtran-filler-RRGGBB-overflow.txt
   Fixes bug that was introduced in version 1.0.2
   This bug was widely publicised in December 2002 and
   has been fixed in many Linux distributions.  Mitre
   named this vulnerability CAN-2002-1363.  Use to patch
   libpng-1.0.5 through 1.2.5

   libpng-patch01-pngrtran-filler-GG-overflow.txt
   Fixes bug that was introduced in version 1.0.2
   This bug was also publicised around January 2003.
   Because of its similarity to patch00, there has been
   some confusion and hardly anyone has applied this
   patch.  There was a flurry of bug reports about this
   in June 2004 when people noticed that only half of
   the problem had been fixed.  Mitre has assigned
   a new name, CAN-2004-0768, to this vulnerability.

   libpng-patch02-pngerror-memcpy-overflow.txt
   This bug was discovered in April 2004 and has been
   widely reported and patched (use patch02a for versions
   1.2.3 and older).

   libpng-patch03-trns-chunk-overflow.txt
   This fixes the most dangerous of the newly reported
   vulnerabilities, which is CERT VU#388984 and Item 1 of
   CAN-2004-0597 (use patch03a for versions 0.89 through
   1.0.5 and patch3b for versions 1.0.6 through 1.0.8).

   libpng-patch04-get-uint-31.txt
   This patch defines PNG_UINT_31_MAX, PNG_UINT_32_MAX, PNG_SIZE_MAX,
   and png_get_uint_31(), which are needed by patches 05-08
   (use patch04a for libpng-1.0.5, patch04b for patch libpng-1.0.2
   through 1.0.3, and patch04c for libpng-1.0.0 through 1.0.1).

   libpng-patch05-pngpread-chunklength.txt
   Fixes CERT VU#817368. Requires one of libpng-patch04*

   Use libpng-patch06-pngread-chunklength.txt to patch libpng-1.0.13
   Fixes CERT VU#286464.  Requires libpng-patch04-* (use patch06a for
   libpng-1.0.0 through 1.0.12, 1.2.0, and 1.2.1).

   libpng-patch07-png-read-png-overflow.txt
   Fixes CERT VU#160448, CAN-2004-0599.  Libpng-1.0.5 and earlier didn't
   implement png_read_png().  Requires libpng-patch04-*

   libpng-patch08-splt-buffer-overflow.txt
   Fixes CERT VU#477512, CAN-2004-0598 (use patch08a to patch libpng-1.0.6
   through 1.0.13, 1.2.0 through 1.2.3. Libpng-1.0.5 and earlier
   didn't implement sPLT chunk reading.  Requires libpng-patch04-*

   libpng-patch09-null-iccp-profile.txt
   Use to patch libpng-1.0.9 through 1.2.5
   Fixes CERT VU#236656, CAN-2004-0598.
   Does not work with libpng-1.0.6-1.0.8.
   Libpng-1.0.5 and earlier didn't implement iCCP chunk reading.

   libpng-patch10-find-duplicate-chunk.txt
   No security problem.  The bugs are similar to the one fixed
   in patch 03, but the only effect is that libpng will fail to
   detect misplaced harmless duplicate chunks.
   Use to patch libpng-1.0.6 through 1.2.5

   libpng-patch11-limit-dimensions.txt
   This patch avoids a host of security problems related to buffer
   overflows that might occur when processing very large images.  It
   causes the reader to reject any images having more than one million
   rows or one milliion columns (use patch11a to patch libpng-0.96
   through 1.0.9, patch11b to patch libpng-0.95, patch11c to patch
   libpng-0.90, and patch11d patch libpng-0.89c.




                    PATCHING LIBPNG LIBRARIES

We are also supplying combined patches that fix all of the
vulnerabilities in a particular libpng distribution.  This table
identifies the proper combined patch for patching each pristine
libpng distribution:


lib version    combined patch                includes individual patches
============= ============================  =================================
libpng-0.89c  libpng-0.89c-all-patches.txt  03a 11d
libpng-0.90   libpng-0.90-all-patches.txt   03a 11c
libpng-0.95   libpng-0.95-all-patches.txt   03a 04c 05 06a 11b
libpng-0.96   libpng-1.0.1-all-patches.txt  03a 04c 05 06a 11a
libpng-0.98   libpng-1.0.1-all-patches.txt  03a 04c 05 06a 11a

libpng-0.99   libpng-1.0.1-all-patches.txt  03a 04c 05 06a 11a
libpng-1.00   libpng-1.0.1-all-patches.txt  03a 04c 05 06a 11a
libpng-1.01   libpng-1.0.1-all-patches.txt  03a 04c 05 06a 11a
libpng-1.0.2  libpng-1.0.3-all-patches.txt  00-01 03a 04b 05 06a 11a
libpng-1.0.3  libpng-1.0.3-all-patches.txt  00-01 03a 04b 05 06a 11a

libpng-1.0.5  libpng-1.0.5-all-patches.txt  00-01 03a 04a 05 06a 11a
libpng-1.0.6  libpng-1.0.8-all-patches.txt  00-01 03b 04-05 06a 07 08a 10 11a
libpng-1.0.7  libpng-1.0.8-all-patches.txt  00-01 03b 04-05 06a 07 08a 10 11a
libpng-1.0.8  libpng-1.0.8-all-patches.txt  00-01 03b 04-05 06a 07 08a 10 11a
libpng-1.0.9  libpng-1.0.9-all-patches.txt  00-01 02a 03-05 06a 07 08a 9-10 11a

libpng-1.0.10 libpng-1.2.1-all-patches.txt  00-01 02a 03-05 06a 07 08a 09-11
libpng-1.0.11 libpng-1.2.1-all-patches.txt  00-01 02a 03-05 06a 07 08a 09-11
libpng-1.0.12 libpng-1.2.1-all-patches.txt  00-01 02a 03-05 06a 07 08a 09-11
libpng-1.0.13 libpng-1.2.2-all-patches.txt  00-01 02a 03-07 08a 09-11
libpng-1.0.14 libpng-1.2.5-all-patches.txt  00-11

libpng-1.0.15 libpng-1.2.5-all-patches.txt  00-11
libpng-1.2.0  libpng-1.2.1-all-patches.txt  00-01 02a 03-05 06a 07 08a 09-11
libpng-1.2.1  libpng-1.2.1-all-patches.txt  00-01 02a 03-05 06a 07 08a 09-11
libpng-1.2.2  libpng-1.2.2-all-patches.txt  00-01 02a 03-07 08a 09-11
libpng-1.2.3  libpng-1.2.3-all-patches.txt  00-07 08a 09-11

libpng-1.2.4  libpng-1.2.5-all-patches.txt  00-11
libpng-1.2.5  libpng-1.2.5-all-patches.txt  00-11





                Patching applications that use libpng

You can also bullet-proof your *application* whether
it is being run with a vulnerable libpng or not.  Use a warning callback
(which you register with libpng's png_read_create_struct() )
similar to this:

void
warning_callback(png_structp png_ptr, png_const_charp warning_msg)
{
  /* convert tRNS warning to error */
  if (strncmp(warning_msg,"Missing PLTE before tRNS",24) == 0)
    png_error(png_ptr, warning_msg);
  printf("libpng warning: %s.\n",warning_msg);
}

If you already have a warning callback function, just add the
two-line "if (strncmp ... png_error()" statement.




You can also protect your application from existing or future
vulnerabilities in the parts of libpng that process chunks that
you don't use.  This method will cause libpng to skip over your unused
chunks.  You will need to add or subtract chunk names from the list,
as appropriate for your application.  This method only works if
you are doing sequential reading.

#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
  png_byte unused_chunks[]=
       {
        104,  73,  83,  84, '\0',   /* hIST */
        105,  84,  88, 116, '\0',   /* iTXt */
        112,  67,  65,  76, '\0',   /* pCAL */
        115,  67,  65,  76, '\0',   /* sCAL */
        115,  80,  76,  84, '\0',   /* sPLT */
        116,  69,  88, 116, '\0',   /* tEXt */
        116,  73,  77,  69, '\0',   /* tIME */
        122,  84,  88, 116, '\0',   /* zTXt */
        };
#endif
There is a complete list of integer representations of
chunk types in png.h starting at line 2644.

Put the following after your png_read_create_struct():
#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
  /* Ignore unused chunks */
  png_set_keep_unknown_chunks(png_ptr, 0, unused_chunks,
     (int)sizeof(unused_chunks)/5);
#endif


You may also wish to place limits on the width and height of images
that you will accept.  Test for images exceeding your chosen limit
immediately after your call to png_get_IHDR().  The new default
limit in libpng-1.2.6rc2 and in patch11, above, is 1 million rows
and 1 million columns (down from the default 2.147 billion in
previous versions).





                          PGP KEY

If you need these:

Glenn's PGP public key:

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.0.7 (GNU/Linux)

mQGiBED4f/ARBAC2jTiYEtPe6AalV1v3R9avuGV8vF3qwv/5YANrObxEp4o8nHMf
EpXONYfeXZ45TuO88Fl7awB6UA6xCLNgXFlBUSHwSpjtUKich7ATw5v/GcXkXoC0
ZSeV2egYtVskcc8ScDdAhXhl7e2bFpEFeu72nWaJhYHT9zx11XyJX/gDewCgj2cs
b+IA38nXP3MccZlroLpgH/sEAIbvlGgH7u5f2uIE5PQwlKMRnpQTU/50Nk6La+t8
1Owns9am7fwIgI3Sbps8q6lVtZfANPREeitIDfX1iuMwalFlOLGgyADsbgJ0vEyI
UGkWmOcOxM5rGbgm2uskB1GXYJa9CQvNwTsnMK2UorpG8NlPt11OtEAWxkyQkui6
8XL7A/9MGlKXuud1Y32Wm/9Q20UpocV/Gw1j+jBCuUKftRMcqH9RanHsfu5BdMHY
lCe3MuZ0214dvZsSYAhKwVUcp3e+y3HGMGJKPQEijy+jK/rUi6bLxwmDey0DrSap
IvcxwuMsLg6cFzFhjPKcXZCp2y6PZIFhRcsZRE4qHiPEHYGDeLRDR2xlbm4gUmFu
ZGVycy1QZWhyc29uIChmb3IgbGlicG5nIGlzc3VlcykgPGdsZW5ucnBAaW1hZ2Vt
YWdpY2sub3JnPohZBBMRAgAZBQJA+H/wBAsHAwIDFQIDAxYCAQIeAQIXgAAKCRD/
dg4wrQO2mk5BAKCAuRiBpM9aXj1LbXNq6G5ARFH9RQCbBn4HF6wx5z+aS3Pvzp8U
xqIHPoS5AQ0EQPh/8RAEAKPm+3/407ibig+gJMq1EtFICCE7Dg4kbWYTpONlyw1z
Fv79oXqtiAWA6B3YczqFkpi0iWlN4JTu06UkGRC5F/0xu+rPeQ67mRPeGaIXvKFn
Ntu3N7qLj7VnEfsDsIBilNHrcixn+BlCMUY3/xRtMI0e1IW2tXmfmBugOACqqcZ7
AAMFA/46BNoS/93NnSgiOGzgFfFOScf5vBiVE931D82iTumrhZ+wxMlHCgB3c/zH
7n5gZVuW/eweLUXSTGWIXxyPlHnZfQ4PzPU0S3Ogr4Ah5yDPMwTHBGGeUM2zMEpE
iuqQcLiaHBbvpWT+KcFXTTlKkRMM0d3eH5vHD3jFeiutSwQQU4hGBBgRAgAGBQJA
+H/xAAoJEP92DjCtA7aaGNIAnRchgPXoTA6ObXLxaZY4f14B2S/TAJ9CjfQ0dqbb
KPQU9s0uJpz3xAcATJkAjQM/jKH+AYABBAC9NCzLIR4o5hjIggPpu9VY83d5HYqU
R10cuz6ZrykGybhyuVFl2dDyNVtKfX/lDbqzBM2EomgBmmohgrxSbhzyNFULWGoH
XgG7H65OJ+Et9DVgYY4VskCHJ1exMS2aQPkji56VOt6AOy1L8v3PmVsZ/W2Xl75I
wA+WdjTU/3VQFQAFEbQoQ0VSVCBDb29yZGluYXRpb24gQ2VudGVyIDxjZXJ0QGNl
cnQub3JnPokAlQMFED+Mof6WdjTU/3VQFQEB5j8D/R6otQdfaMuVmcnj88IElauy
Fi7Nv34MdqqEHP9q/SH5FfBQBAw63zixPpWd/zG7TcnwIswvf3HhA9o8rCgW6aGa
WVWoNTkwL90JaMWEZxtT+JLP1qQ1TMb/PSndFIyAQH6b0x4uKtI8PASsOczo0TLH
lODhKTJ6Jyz9HUuzc6X4iEYEEBECAAYFAj+NS0wACgkQXYr3tqcKhGMLBQCgv6+7
Q/9o18vixI92Jkm298yZEVcAoKjPdBVmrM6T6CzvoHW9DO73EErsiEYEEBECAAYF
Aj+NS18ACgkQHWlMw1Rb3MQVgwCgzJldauEoDW1DvZqrYdwdyFcsPlwAnRm4zB5/
NSnkUJQFBqXYs2f1P6PEiEwEExECAAwFAj+NT3wFgwH5koIACgkQSQjoesB49NKW
wQCdF71rr7dhNElR1o2sP6TP3fyGzVYAn2NYpp94oK/VX92dAHOG7QRlhdSD
=gO8S
-----END PGP PUBLIC KEY BLOCK-----

Key fingerprint = E0CB 3EE8 AF21 9B24 FD3F  4219 FF76 0E30 AD03 B69A

---------------------
rev 004 9 August 2004