Bug 541698 (CVE-2009-4134, CVE-2010-1449, CVE-2010-1450)

Summary: CVE-2009-4134 CVE-2010-1449 CVE-2010-1450 python: rgbimg: multiple security issues
Product: [Other] Security Response Reporter: Jan Lieskovsky <jlieskov>
Component: vulnerabilityAssignee: Red Hat Product Security <security-response-team>
Status: CLOSED ERRATA QA Contact:
Severity: low Docs Contact:
Priority: low    
Version: unspecifiedCC: bressers, dmalcolm, jantill, psplicha, security-response-team, vdanen
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard: impact=low,source=redhat,reported=20091126,public=20100510,cvss2=5.1/AV:N/AC:H/Au:N/C:P/I:P/A:P
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
: 644425 650936 (view as bug list) Environment:
Last Closed: 2011-02-17 10:09:25 EST Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Bug Depends On: 644425, 650936    
Bug Blocks:    
Attachments:
Description Flags
Patch none

Description Jan Lieskovsky 2009-11-26 13:44:04 EST
Marc Schoenefeld found an invalid pointer dereference flaw,
present in Python's RGB image processing module. An attacker
could provide a specially-crafted black-and-white (B/W) RGB
image, which once processed by Python's RGB module would
lead to denial of service (Python VM crash).
Comment 3 Jan Lieskovsky 2009-11-26 13:52:10 EST
This issue affects the versions of python package, as shipped with
Red Hat Enterprise Linux 3, 4, and 5.
Comment 9 Tomas Hoger 2010-05-04 05:17:50 EDT
I will refer to this SGI image format spec below:
  ftp://ftp.sgi.com/graphics/SGIIMAGESPEC

The crash triggered by Marc's reproducer is a buffer underflow caused by an unexpectedly large ZSIZE (number of channels) value.  The spec defines certain typical ZSIZE values (1 for B/W, 3 for RGB, 4 for RGB+Alpha), but it does not forbid greater values.  ZSIZE is read as 16bit value from the image header, so values up to 0xffff can be specified.

rgbimgmodule implementation assumes that ZSIZE <= 4, but does not check that.  It uses 32bit value to store info for one pixel (so up to 4 channels, module only supports 1 byte per channel, BPC == 2 images are not supported) and uses pattern 3-z (for z in 0 .. ZSIZE-1) to adjust the pointer position within a 32bit value used to store one pixel to write particular channel data.  Therefore, interleaverow() can be called with its third argument having a negative value, resulting in buffer underflow.

In case of Marc's reproducer, input file was truncated after YSIZE and ZSIZE was not specified in the file at all.  rgbimgmodule does not have EOF / file truncation checks, so ZSIZE value was rather unpredictable and possibly different for each run.


In addition, there is also an integer overflow leading to buffer under-allocation and overflow:

    rv = PyString_FromStringAndSize((char *) 0,
                   (xsize*ysize+TAGLEN)*sizeof(Py_Int32));

There was and attempt to fix in as part of CVE-2008-3143 (bug #455013):

http://svn.python.org/view?view=rev&revision=60793
http://svn.python.org/view/python/branches/release25-maint/Modules/rgbimgmodule.c?r1=60793&r2=60792

using the code:

    new_size = xsize * ysize + TAGLEN;
    if (new_size < 0 || (new_size * sizeof(Py_Int32)) < 0) {
        PyErr_NoMemory();

This check is insufficient though (e.g. for xsize = ysize = 0x8000, new_size is 0x40000000 and new_size * sizeof(Py_Int32) is 0).
Comment 10 Tomas Hoger 2010-05-04 08:27:16 EDT
Two more bonus flaws in RLE decoder:

longimagedata() contains two copies of this:

  fread(rledat, lengthtab[idx], 1, inf);

where lengthtab[idx] is 32bit value read form the image file.  rledat size (rlebuflen) is derived form XSIZE.  On one of the code paths, there's a check to ensure that lengthtab[idx] does not exceed rlebuflen, but not on the other one.


Another issue is in expandrow().  The amount of uncompressed / decoded data written to the output buffer is only controlled by the input from the file, not checking any output buffer boundaries.
Comment 12 Tomas Hoger 2010-05-05 02:57:05 EDT
Created attachment 411489 [details]
Patch

It adds following:
- checks that ZSIZE does not exceed 4
- corrects broken integer overflow checks, unneeded check are dropped /
  replaced by comment indicating no overflow can happen
- check against rlebuflen before reading data to rledat
- only allow expandrow() to write XSIZE bytes (one scanline)

It adds basic sanity check to longstoimage() (image writing) too.

This patch should be applied after reverting rgbimgmodule.c changes from CVE-2008-3143 patch.
Comment 13 Tomas Hoger 2010-05-05 05:24:26 EDT
CVE assignments:

CVE-2009-4134 - for the original issue - buffer underflow caused by unexpected ZSIZE value, as pointed out in comment #0 and further detailed in comment #9

CVE-2010-1449 - incorrect integer overflow checks, incomplete fix for rgbimg part of the CVE-2008-3143, detailed in comment #9

CVE-2010-1450 - multiple RLE decoder buffer overflows, detailed in comment #10
Comment 14 Tomas Hoger 2010-05-10 09:46:05 EDT
Making the bug public.
Comment 15 Tomas Hoger 2010-05-11 03:12:37 EDT
Upstream bug report:
  http://bugs.python.org/issue8678
Comment 16 Tomas Hoger 2010-05-25 10:29:10 EDT
Statement:

The Red Hat Security Response Team has rated this issue as having low security
impact, a future update may address this flaw.
Comment 22 errata-xmlrpc 2011-01-14 04:03:53 EST
This issue has been addressed in following products:

  Red Hat Enterprise Linux 5

Via RHSA-2011:0027 https://rhn.redhat.com/errata/RHSA-2011-0027.html
Comment 23 errata-xmlrpc 2011-02-16 09:19:12 EST
This issue has been addressed in following products:

  Red Hat Enterprise Linux 4

Via RHSA-2011:0260 https://rhn.redhat.com/errata/RHSA-2011-0260.html