Bug 725760 - CVE-2011-2895 libXfont: LZW decompression heap corruption / infinite loop
Summary: CVE-2011-2895 libXfont: LZW decompression heap corruption / infinite loop
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
high
high
Target Milestone: ---
Assignee: Red Hat Product Security
QA Contact:
URL:
Whiteboard:
Depends On: 728442 728443 728444 728445 728447 729870 752934 833925
Blocks: 714279 CVE-2011-2895 752971
TreeView+ depends on / blocked
 
Reported: 2011-07-26 13:41 UTC by Tomas Hoger
Modified: 2019-09-29 12:46 UTC (History)
4 users (show)

Fixed In Version: libXfont 1.4.4
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2012-06-20 15:24:28 UTC
Embargoed:


Attachments (Terms of Use)
My proposed patch - variant 1 (944 bytes, patch)
2011-08-04 14:07 UTC, Tomas Hoger
no flags Details | Diff
My proposed patch - variant 2 (584 bytes, patch)
2011-08-04 14:08 UTC, Tomas Hoger
no flags Details | Diff
Updated proposed patch (521 bytes, patch)
2011-08-04 18:00 UTC, Tomas Hoger
no flags Details | Diff


Links
System ID Private Priority Status Summary Last Updated
Novell 709851 0 None None None Never
Red Hat Product Errata RHSA-2011:1154 0 normal SHIPPED_LIVE Important: libXfont security update 2011-08-11 21:36:10 UTC
Red Hat Product Errata RHSA-2011:1155 0 normal SHIPPED_LIVE Important: xorg-x11 security update 2011-08-11 21:56:34 UTC
Red Hat Product Errata RHSA-2011:1834 0 normal SHIPPED_LIVE Important: libXfont security update 2011-12-19 22:51:02 UTC

Description Tomas Hoger 2011-07-26 13:41:27 UTC
libXfont contains a compress / LZW decompressor implementation.  This implementation does not correctly handle compressed streams that contain code words that were not yet added to the decompression table.  LZW decompression has a special case (a KwKwK string) when code word matches the first free entry in the decompression table.  The implementation used in libXfont allow code words not only matching, but also exceeding the first free entry.

Relevant code appears in BufCompressedFill() in src/fontfile/decompress.c:

        /*
         * Special case for KwKwK string.
         */
        if ( code >= file->free_ent ) {
            *stackp++ = finchar;
            code = oldcode;
        }

http://cgit.freedesktop.org/xorg/lib/libXfont/tree/src/fontfile/decompress.c?id=f29f1d68d7eca96e45ba3758686be07993d82e03#n249

This allows creating a loop in the decompression table, which leads to an "infinite" loop:

        /*
         * Generate output characters in reverse order
         */
        while ( code >= 256 )
        {
            *stackp++ = file->tab_suffix[code];
            code = file->tab_prefix[code];
        }

http://cgit.freedesktop.org/xorg/lib/libXfont/tree/src/fontfile/decompress.c?id=f29f1d68d7eca96e45ba3758686be07993d82e03#n257

and heap-based buffer overflow (CompressedFile's de_stack[]):

        char_type       de_stack[STACK_SIZE];
        char_type       *tab_suffix;
        unsigned short  *tab_prefix;
    } CompressedFile;

http://cgit.freedesktop.org/xorg/lib/libXfont/tree/src/fontfile/decompress.c?id=f29f1d68d7eca96e45ba3758686be07993d82e03#n121


Once stackp is incremented to point to after de_stack[] buffer end, tab_suffix and tab_prefix pointers are corrupted, which may lead to arbitrary memory corruption.  libXfont is used by X server and can parse arbitrary user-supplied font file.  Successful exploitation may possibly lead to a local privilege escalation.

Comment 1 Tomas Hoger 2011-07-26 13:48:07 UTC
(In reply to comment #0)
> libXfont contains a compress / LZW decompressor implementation.

LZW decompression implementations in libXfont, ncompress and gzip all seem to be based on the same implementation.  ncompress and gzip already contain a check for code > free_ent and abort decompression in such case.  Other code bases derived from the same source (such as GIF parsers in mozilla/libpr0n and gd) check for stack[] overflow in the while loop.

Comment 3 Tomas Hoger 2011-08-04 14:07:23 UTC
Created attachment 516719 [details]
My proposed patch - variant 1

Checks code values, similar to ncompress/gzip.

Comment 4 Tomas Hoger 2011-08-04 14:08:05 UTC
Created attachment 516721 [details]
My proposed patch - variant 2

de_stack overflow check in the while loop, similar to what OpenBSD compress does.

Comment 5 Tomas Hoger 2011-08-04 18:00:34 UTC
Created attachment 516759 [details]
Updated proposed patch

Comment 8 Tomas Hoger 2011-08-10 18:14:05 UTC
Making this public.

Comment 10 Tomas Hoger 2011-08-11 06:18:52 UTC
Created libXfont tracking bugs for this issue

Affects: fedora-all [bug 729870]

Comment 11 errata-xmlrpc 2011-08-11 21:36:16 UTC
This issue has been addressed in following products:

  Red Hat Enterprise Linux 5
  Red Hat Enterprise Linux 6

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

Comment 12 errata-xmlrpc 2011-08-11 21:56:42 UTC
This issue has been addressed in following products:

  Red Hat Enterprise Linux 4

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

Comment 13 Tomas Hoger 2011-09-27 14:10:01 UTC
An improved fix was committed to upstream git repository.  It improves input checks to avoid decompression table loops and increases decompression stack size, instead of performing stack boundary checks:

http://cgit.freedesktop.org/xorg/lib/libXfont/commit/src/fontfile/decompress.c?id=bd48ad11fd11412c62c3ac8ed5d52c4f10a985aa

Comment 15 errata-xmlrpc 2011-12-19 17:51:38 UTC
This issue has been addressed in following products:

  Red Hat Enterprise Linux 5.6.Z - Server Only

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


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