Bug 524222 (CVE-2009-3292) - CVE-2009-3292 php: exif extension: Multiple missing sanity checks in EXIF file processing
Summary: CVE-2009-3292 php: exif extension: Multiple missing sanity checks in EXIF fil...
Keywords:
Status: CLOSED ERRATA
Alias: CVE-2009-3292
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
low
low
Target Milestone: ---
Assignee: Red Hat Product Security
QA Contact:
URL: http://www.php.net/ChangeLog-5.php
Whiteboard:
Depends On: 541594 541595 541596 541597 541598
Blocks:
TreeView+ depends on / blocked
 
Reported: 2009-09-18 12:58 UTC by Jan Lieskovsky
Modified: 2019-09-29 12:32 UTC (History)
6 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2010-01-14 09:24:39 UTC
Embargoed:


Attachments (Terms of Use)
Local copy of PHP-5.2.11 EXIF sanity patch. (3.05 KB, patch)
2009-09-18 13:01 UTC, Jan Lieskovsky
no flags Details | Diff


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHSA-2010:0040 0 normal SHIPPED_LIVE Moderate: php security update 2010-01-13 18:09:32 UTC

Description Jan Lieskovsky 2009-09-18 12:58:38 UTC
Multiple missing sanity checks for proper file form were found in php,
when processing Exchangeable Image File Format (EXIF) image files.
A remote attacker could provide a specially-crafted EXIF image file,
leading to php application, using the EXIF extension, crash, once
processed. 

References:
-----------
http://www.php.net/ChangeLog-5.php

Upstream patch:
---------------
http://svn.php.net/viewvc?view=revision&revision=287371

Comment 1 Jan Lieskovsky 2009-09-18 13:01:55 UTC
Created attachment 361646 [details]
Local copy of PHP-5.2.11 EXIF sanity patch.

Comment 2 Jan Lieskovsky 2009-09-18 13:02:30 UTC
This issue affects the versions of php package, as shipped with Red Hat
Enterprise Linux 3, 4, and 5.

Comment 3 Jan Lieskovsky 2009-09-22 08:56:06 UTC
MITRE's CVE-2009-3292 record:
-----------------------------

Unspecified vulnerability in PHP before 5.2.11 has unknown impact and
attack vectors related to "missing sanity checks around exif
processing."

References:
-----------
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-3292
http://www.php.net/ChangeLog-5.php#5.2.11
http://www.php.net/releases/5_2_11.php
http://www.osvdb.org/58186
http://secunia.com/advisories/36791

Comment 4 Tomas Hoger 2009-09-25 13:55:47 UTC
Upstream patch introduces 3 changes:

- length check in exif_process_APP1()

-	if (memcmp(CharBuf+2, ExifHeader, 6)) {
+	if (length <= 8 || memcmp(CharBuf+2, ExifHeader, 6)) {

This change is not very interesting for memcmp() call on the same line, as possible buffer over-read is rather short here.

More interesting is a subsequent call to exif_process_TIFF_in_JPEG():

exif_process_TIFF_in_JPEG(ImageInfo, CharBuf + 8, length - 8, displacement+8 TSRMLS_CC);

There, length - 8 can integer underflow, passing negative (or actually very large positive value, as unsigned size_t type is used for length parameters) is passed to the function.  Later on, this length value is used as an upper bound when reading more data from CharBuf buffer, that contains EXIF info loaded from the file.  It should be noted that when length <= 8, all data later read in exif_process_TIFF_in_JPEG() are not reliably controlled by an attacker, so EXIF parsing may fail on any of the checks done in the function (e.g. where EXIF data format is determined).  Theoretically, memory may contain desired data from some previous calls, so the checks may pass and offset_of_ifd may get set to a large value, allow further buffer over-reads, that may cause interpreter crash or (quite unlikely) cause PHP exif functions to leak some data from interpreters memory.

So impact and low severity rating identical to similar problem fixed in PHP 5.2.10 - see bug #506896.


- EOF checking when reading lh / ll

-		lh = php_stream_getc(ImageInfo->infile);
-		ll = php_stream_getc(ImageInfo->infile);
+		if ((lh = php_stream_getc(ImageInfo->infile)) == EOF) {
+			EXIF_ERRLOG_CORRUPT(ImageInfo)
+			return FALSE;
+		}
+		if ((ll = php_stream_getc(ImageInfo->infile)) == EOF) {
+			EXIF_ERRLOG_CORRUPT(ImageInfo)
+			return FALSE;
+		}

We can ignore lh case completely, as EOF in reading lh means EOF for ll.  EOF is defined as (-1), so when assigned to unsigned lh / ll, those variables will hold UINT_MAX (0xFFFFFFFF on both 32 and 64 bit arches).

lh and ll is used to calculate itemlen:
  itemlen = (lh << 8) | ll;

Given the "| ll", if ll is 0xFFFFFFFF, we can ignore lh completely.

itemlen is then used passed to exif_file_sections_add() as:
  sn = exif_file_sections_add(ImageInfo, marker, itemlen+1, NULL);

size argument of exif_file_sections_add() is size_t, so it will be 0 on 32 bit arches, 2^32 on 64 bits.  This size is used as data buffer size:

    if (!size) {
        data = NULL;
    } else if (data == NULL) {
        data = safe_emalloc(size, 1, 0);
    }

On 32 bits, no buffer is allocated, which leads to a NULL pointer dereference back in exif_scan_JPEG_header():

        Data = ImageInfo->file.list[sn].data;  // data is NULL

        /* Store first two pre-read bytes. */
        Data[0] = (uchar)lh;
        Data[1] = (uchar)ll;

On 64 bits, there's an attempt to allocate large amount of memory (4G).  This is likely to fail on PHP's memory_limit (values between 32M (default) and 128M are common) or system memory limit, or allocate large buffer if no limits are set (unlikely).


- MAX_IFD_NESTING_LEVEL check for TIFF exif header

It seems this may cause PHP to process EXIF data in loop until execution time limit is hit.

Comment 5 Tomas Hoger 2009-09-29 13:32:47 UTC
(In reply to comment #4)
> - MAX_IFD_NESTING_LEVEL check for TIFF exif header
> 
> It seems this may cause PHP to process EXIF data in loop until execution time
> limit is hit.  

To correct myself...  This problem causes exif_process_IFD_in_TIFF() to be called recursively without limiting the depth of recursion.  Hence this exhausts all stack memory and results in php process crash in a fraction of the default execution time limit.  Hence impact=low too.

Comment 8 errata-xmlrpc 2010-01-13 18:10:21 UTC
This issue has been addressed in following products:

  Red Hat Enterprise Linux 5
  Red Hat Enterprise Linux 4
  Red Hat Enterprise Linux 3

Via RHSA-2010:0040 https://rhn.redhat.com/errata/RHSA-2010-0040.html


Note You need to log in before you can comment on or make changes to this bug.