Bug 135393 - CAN-2004-0888 xpdf integer overflows (CAN-2005-0206)
CAN-2004-0888 xpdf integer overflows (CAN-2005-0206)
Status: CLOSED ERRATA
Product: Red Hat Enterprise Linux 3
Classification: Red Hat
Component: xpdf (Show other bugs)
3.0
All Linux
medium Severity medium
: ---
: ---
Assigned To: Ngo Than
Mike McLean
: Security
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2004-10-12 10:20 EDT by Mark J. Cox (Product Security)
Modified: 2007-11-30 17:07 EST (History)
3 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2005-03-04 04:14:23 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
Patch for CAN-2004-0888 (2.59 KB, patch)
2004-10-12 10:21 EDT, Mark J. Cox (Product Security)
no flags Details | Diff
bad1.pdf demo exploit pdf file. (49 bytes, application/octet-stream)
2004-10-14 16:04 EDT, Josh Bressers
no flags Details
bad2.pdf demo exploit pdf file (54 bytes, application/octet-stream)
2004-10-14 16:05 EDT, Josh Bressers
no flags Details
bad3.pdf demo exploit pdf file (109 bytes, application/octet-stream)
2004-10-14 16:06 EDT, Josh Bressers
no flags Details
bad4.pdf demo exploit pdf file (44 bytes, application/octet-stream)
2004-10-14 16:09 EDT, Josh Bressers
no flags Details
bad5.pdf demo exploit pdf file (72 bytes, application/octet-stream)
2004-10-14 16:09 EDT, Josh Bressers
no flags Details
The fixed patch with explicit casting (its teTeX variant). (2.62 KB, patch)
2005-02-03 09:44 EST, Jindrich Novy
no flags Details | Diff

  None (edit)
Description Mark J. Cox (Product Security) 2004-10-12 10:20:21 EDT
During a source code audit, Chris Evans and others discovered a number
of integer overflow bugs that affected all versions of xpdf.  An
attacker could construct a carefully crafted PDF file that could cause
xpdf to crash or possibly execute arbitrary code when opened.  

        CAN-2004-0888 Affects: 2.1AS 2.1AW 2.1ES 2.1WS
        CAN-2004-0888 Affects: 3AS 3ES 3WS 3Desktop

This issue is embargoed until Oct20 1400UTC
Comment 1 Mark J. Cox (Product Security) 2004-10-12 10:21:40 EDT
Created attachment 105059 [details]
Patch for CAN-2004-0888
Comment 2 Josh Bressers 2004-10-14 16:04:58 EDT
Created attachment 105228 [details]
bad1.pdf demo exploit pdf file.
Comment 3 Josh Bressers 2004-10-14 16:05:35 EDT
Created attachment 105229 [details]
bad2.pdf demo exploit pdf file
Comment 4 Josh Bressers 2004-10-14 16:06:25 EDT
Created attachment 105230 [details]
bad3.pdf demo exploit pdf file
Comment 5 Josh Bressers 2004-10-14 16:09:01 EDT
Created attachment 105231 [details]
bad4.pdf demo exploit pdf file
Comment 6 Josh Bressers 2004-10-14 16:09:52 EDT
Created attachment 105232 [details]
bad5.pdf demo exploit pdf file
Comment 7 Josh Bressers 2004-10-21 12:25:10 EDT
removing embargo
Comment 8 Michal Jaegermann 2004-10-25 15:08:13 EDT
In a patch for this issue in xpdf-3.00-3.4 from fc2 there is a comment
in Catalog.cc which says:

  // The gcc doesnt optimize this away, so this check is ok,
  // even if it looks like a pagesSize != pagesSize check.
  if (pagesSize*sizeof(Page *)/sizeof(Page *) != pagesSize ||
      pagesSize*sizeof(Ref)/sizeof(Ref) != pagesSize) { ... }

I found that at least with some versions of gcc this is actually
not the case.  If a variable in question was just assigned to then
optimizer indeed leaves that alone.  Otherwise the whole test,
and a block guarded by it, may disappear.  If an auxilliary
variable is used, to which something like pagesSize*sizeof(Page *)
is assigned, then the test is not optimized away.  The same,
of course, applies to assorted tests in XRef.cc

In any case depending in security patches that some particular
version of an optimizer will not screw us up does not seem like
a good plan.

A version of gcc where I run into that was gcc-2.96-113.  At least
RHEL2.1 may be affected and who knows what else.
Comment 9 Ngo Than 2004-10-26 10:40:22 EDT
it's a know issue, i have added a workaround in xpdf for rhel2.1 and
rhel3 and it works fine.
Comment 10 Josh Bressers 2004-10-27 11:17:33 EDT
An errata has been issued which should help the problem 
described in this bug report. This report is therefore being 
closed with a resolution of ERRATA. For more information
on the solution and/or where to find the updated files, 
please follow the link below. You may reopen this bug report 
if the solution does not work for you.

http://rhn.redhat.com/errata/RHSA-2004-592.html
Comment 11 Jindrich Novy 2005-02-03 09:30:53 EST
The patch to fix CAN-2004-888 seems to be broken on all 64bit
platforms (tested only on ia64 though), because of the fact that the
overflow checking:

if (size*sizeof(XRefEntry)/sizeof(XRefEntry) !=  size) {
  ... error ...
}

won't succeed, because the left side of the condition is evaluated as
64bit integer by default. (all the arithmetic in the expression is
done in the widest integer type, which is 64bit, because of
sizeof(XRefEntry), even if "size" is 32bit so the explicit casting in
the numerator of the fraction has to be added).

In case of memory allocation:

entries = (XRefEntry *)gmalloc(size * sizeof(XRefEntry));

it's truncated to 32bits as prototype of gmalloc is:

void *gmalloc(int);

so the overflow check won't detect the overflow presented by bad5.pdf
and leads to segfault, because gmalloc succeeds with an allocation
request of 8 bytes:

Program received signal SIGSEGV, Segmentation fault.
XRef (this=0x6000000000279080, strA=0x6000000000278f20, ownerPassword=0x0,
userPassword=0x0) at XRef.cc:89
89            entries[i].used = gFalse;
Current language:  auto; currently c++
(gdb) p size
$1 = 357913942
(gdb) p sizeof(XRefEntry)
$2 = 12
(gdb) p size*sizeof(XRefEntry)
$3 = 4294967304
(gdb) p size*sizeof(XRefEntry)&((1<<32)-1)
$4 = 8
Comment 12 Jindrich Novy 2005-02-03 09:44:25 EST
Created attachment 110599 [details]
The fixed patch with explicit casting (its teTeX variant).
Comment 13 Tim Waugh 2005-02-04 10:23:27 EST
Wait a minute -- this patch drops a check from the last hunk:

  pagesSize*sizeof(Ref)/sizeof(Ref) != pagesSize

Surely that's not intentional?
Comment 14 Jindrich Novy 2005-02-07 06:44:13 EST
Isn't this check in the first hunk where Catalog.cc is patched?
Comment 15 Tim Waugh 2005-02-07 07:10:43 EST
Sorry, I meant the last hunk of the interdiff.
Comment 16 Ngo Than 2005-02-07 08:55:40 EST
yes, it's missing in the obove patch. it should look:
@@ -186,6 +192,11 @@
       }
       if (start >= pagesSize) {
        pagesSize += 32;
+        if (pagesSize*(int)sizeof(Page *)/sizeof(Page *) != pagesSize ||
+            pagesSize*(int)sizeof(Ref)/sizeof(Ref) != pagesSize) {
+          error(-1, "Invalid 'pagesSize' parameter.");
+          goto err3;
+        }
Comment 17 Ngo Than 2005-02-07 09:51:45 EST
i have added the fix in xpdf-2.02-9.6 and xpdf-0.92-14.
Comment 18 Josh Bressers 2005-02-23 13:48:39 EST
A new CVE id has been assigned to instances which have the CAN-2004-0888
incomplete fix.  The new CVE id is CAN-2005-0206.
Comment 19 Mark J. Cox (Product Security) 2005-03-04 04:14:24 EST
An advisory has been issued which should help the problem
described in this bug report. This report is therefore being
closed with a resolution of ERRATA. For more information
on the solution and/or where to find the updated files,
please follow the link below. You may reopen this bug report
if the solution does not work for you.

http://rhn.redhat.com/errata/RHSA-2005-213.html

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