Hi xpdf/cupsys/tetex-bin maintainers, hi Debian security team! Markus Meissner discovered even more instances of integer overflows (see CAN-2004-0888), see forwarded message below. Several packages follow the bad habit to include xpdf source code; among them are tetex-bin and cupsys, other ones are not supported by Ubuntu. I prepared updated Ubuntu packages for xpdf, cupsys and tetex-bin, which are based on Markus's patches. However, Debian/Ubuntu use slightly different solutions for the former bugs, so my patches look a bit different. Find attached the package interdiffs aganst tetex-bin_2.0.2-23, xpdf_3.00-9, and cupsys_1.1.20final+rc1-10. Our version numbers do not directly follow fhese Debian versions, but should apply cleanly to them. Thanks for considering and have a nice day! Martin ----- Forwarded message from Matt Zimmerman <mdz@canonical.com> ----- From: Marcus Meissner <meissner@suse.de> To: vendor-sec@lst.de Cc: derekn@foolabs.com Subject: [vendor-sec] xpdf .... 64bit fun Date: Fri, 29 Oct 2004 15:50:53 +0200 Hi folks, hi Derek, Our QA Team noted problems with the xpdf and clones updates on 64bit systems, notably AMD64. I have identified 2 problems: - We are using "if (size * sizeof(Foo)/sizeof(Foo) != size)" checks, which operate on "size_t" which is 64bit unsigned long on 64bit systems. However Xpdf then goes and calls "g*alloc" its own funny gmalloc/grealloc routines. Which have size passed into as "int" a 32bit quantity. This is happily truncated by the compiler leading again to the mentioned overflow. I have attached a patch against libgoo to change its arguments from int to size_t. Applies to xpdf2 and xpdf3. - Several negative integer conditions went unchecked. I am not sure why this did not show up on 32bit systems, but it does on 64bit systems. Additionaly, at one place the parser could be made to enter an endless loop. I have fixed the most obvious places of those problems, more might be in there. Patch attached. Applies to xpdf2 only, xpdf3 already has checks in place. The goo patch can be considered final I think. The underflow patch is yet another layer of checks and patchwork. I would call this issue public, since it can be reproduced using Chris Evans bad4.pdf and bad5.pdf. Ciao, Marcus diff -ru xpdf-2.02pl1/xpdf/XRef.cc xpdf-2.02pl1/xpdf/XRef.cc --- xpdf-2.02pl1/xpdf/XRef.cc 2004-10-29 15:16:45.790089001 +0200 +++ xpdf-2.02pl1/xpdf/XRef.cc 2004-10-29 15:11:54.132168025 +0200 @@ -66,6 +66,8 @@ start = str->getStart(); pos = readTrailer(); + entries = NULL; + // if there was a problem with the trailer, // try to reconstruct the xref table if (pos == 0) { @@ -76,7 +78,7 @@ // trailer is ok - read the xref table } else { - if (size*sizeof(XRefEntry)/sizeof(XRefEntry) != size) { + if ((size < 0) || (size*sizeof(XRefEntry)/sizeof(XRefEntry) != size)) { error(-1, "Invalid 'size' inside xref table."); ok = gFalse; errCode = errDamaged; @@ -181,7 +183,7 @@ n = atoi(p); while ('0' <= *p && *p <= '9') ++p; while (isspace(*p)) ++p; - if (p == buf) + if ((p == buf) || (n < 0)) /* must make progress */ return 0; pos1 += (p - buf) + n * 20; } @@ -255,6 +257,10 @@ } s[i] = '\0'; first = atoi(s); + if (first < 0) { + error(-1, "Invalid 'first'"); + goto err2; + } while ((c = str->lookChar()) != EOF && isspace(c)) { str->getChar(); } @@ -266,6 +272,10 @@ } s[i] = '\0'; n = atoi(s); + if (n<=0) { + error(-1, "Invalid 'n'"); + goto err2; + } while ((c = str->lookChar()) != EOF && isspace(c)) { str->getChar(); } @@ -273,7 +283,7 @@ // table size if (first + n > size) { newSize = size + 256; - if (newSize*sizeof(XRefEntry)/sizeof(XRefEntry) != newSize) { + if ((newSize < 0) || (newSize*sizeof(XRefEntry)/sizeof(XRefEntry) != newSize)) { error(-1, "Invalid 'newSize'"); goto err2; } @@ -406,6 +416,10 @@ // look for object } else if (isdigit(*p)) { num = atoi(p); + if (num < 0) { + error(-1, "Invalid 'num' parameters."); + return gFalse; + } do { ++p; } while (*p && isdigit(*p)); @@ -425,7 +439,7 @@ if (!strncmp(p, "obj", 3)) { if (num >= size) { newSize = (num + 1 + 255) & ~255; - if (newSize*sizeof(XRefEntry)/sizeof(XRefEntry) != newSize) { + if ((newSize < 0) || (newSize*sizeof(XRefEntry)/sizeof(XRefEntry) != newSize)) { error(-1, "Invalid 'obj' parameters."); return gFalse; } diff -ru xpdf-2.02pl1/goo/gmem.c xpdf-2.02pl1/goo/gmem.c --- xpdf-2.02pl1/goo/gmem.c 2003-06-16 22:01:26.000000000 +0200 +++ xpdf-2.02pl1/goo/gmem.c 2004-10-29 15:13:34.866919791 +0200 @@ -53,9 +53,9 @@ #endif /* DEBUG_MEM */ -void *gmalloc(int size) { +void *gmalloc(size_t size) { #ifdef DEBUG_MEM - int size1; + size_t size1; char *mem; GMemHdr *hdr; void *data; @@ -94,11 +94,11 @@ #endif } -void *grealloc(void *p, int size) { +void *grealloc(void *p, size_t size) { #ifdef DEBUG_MEM GMemHdr *hdr; void *q; - int oldSize; + size_t oldSize; if (size == 0) { if (p) @@ -137,7 +137,7 @@ void gfree(void *p) { #ifdef DEBUG_MEM - int size; + size_t size; GMemHdr *hdr; GMemHdr *prevHdr, *q; int lst; diff -ru xpdf-2.02pl1/goo/gmem.h xpdf-2.02pl1/goo/gmem.h --- xpdf-2.02pl1/goo/gmem.h 2003-06-16 22:01:26.000000000 +0200 +++ xpdf-2.02pl1/goo/gmem.h 2004-10-29 15:13:50.864027201 +0200 @@ -19,13 +19,13 @@ * Same as malloc, but prints error message and exits if malloc() * returns NULL. */ -extern void *gmalloc(int size); +extern void *gmalloc(size_t size); /* * Same as realloc, but prints error message and exits if realloc() * returns NULL. If <p> is NULL, calls malloc instead of realloc(). */ -extern void *grealloc(void *p, int size); +extern void *grealloc(void *p, size_t size); /* * Same as free, but checks for and ignores NULL pointers. ----- End forwarded message ----- -- Martin Pitt http://www.piware.de Ubuntu Developer http://www.ubuntulinux.org Debian GNU/Linux Developer http://www.debian.org
diff -u xpdf-3.00/debian/changelog xpdf-3.00/debian/changelog --- xpdf-3.00/debian/changelog +++ xpdf-3.00/debian/changelog @@ -1,3 +1,16 @@ +xpdf (3.00-9ubuntu2) hoary; urgency=low + + * SECURITY UPDATE: fix potential buffer overflow + * goo/gmem.[ch]: change declarations of gmalloc and grealloc to use size_t + instead of int; int truncated sizes to 32 bits, which made xpdf still + vulnerable to integer (and eventually buffer) overflow attacks on 64 bit + platforms like amd64. + * Thanks to Marcus Meissner <meissner@suse.de> for providing the patch + * References: + CAN-2004-0889 (incomplete fix in version 3.00-9) + + -- Martin Pitt <mpitt@debian.org> Mon, 1 Nov 2004 12:00:47 +0100 + xpdf (3.00-9ubuntu1) hoary; urgency=low * Resynchronise with Debian. only in patch2: unchanged: --- xpdf-3.00.orig/goo/gmem.c +++ xpdf-3.00/goo/gmem.c @@ -53,9 +53,9 @@ #endif /* DEBUG_MEM */ -void *gmalloc(int size) { +void *gmalloc(size_t size) { #ifdef DEBUG_MEM - int size1; + size_t size1; char *mem; GMemHdr *hdr; void *data; @@ -94,11 +94,11 @@ #endif } -void *grealloc(void *p, int size) { +void *grealloc(void *p, size_t size) { #ifdef DEBUG_MEM GMemHdr *hdr; void *q; - int oldSize; + size_t oldSize; if (size == 0) { if (p) @@ -137,7 +137,7 @@ void gfree(void *p) { #ifdef DEBUG_MEM - int size; + size_t size; GMemHdr *hdr; GMemHdr *prevHdr, *q; int lst; only in patch2: unchanged: --- xpdf-3.00.orig/goo/gmem.h +++ xpdf-3.00/goo/gmem.h @@ -19,13 +19,13 @@ * Same as malloc, but prints error message and exits if malloc() * returns NULL. */ -extern void *gmalloc(int size); +extern void *gmalloc(size_t size); /* * Same as realloc, but prints error message and exits if realloc() * returns NULL. If <p> is NULL, calls malloc instead of realloc(). */ -extern void *grealloc(void *p, int size); +extern void *grealloc(void *p, size_t size); /* * Same as free, but checks for and ignores NULL pointers.
diff -u cupsys-1.1.20final+rc1/debian/changelog cupsys-1.1.20final+rc1/debian/changelog --- cupsys-1.1.20final+rc1/debian/changelog +++ cupsys-1.1.20final+rc1/debian/changelog @@ -1,3 +1,15 @@ +cupsys (1.1.20final+rc1-10ubuntu3) hoary; urgency=low + + * SECURITY: still CAN-2004-0888. Updated patch 36pdftopsoverflow.patch: + - pdftops/gmem.[ch]: change declarations of gmalloc and grealloc to use size_t + instead of int; int truncated sizes to 32 bits, which made xpdf still + vulnerable to integer (and eventually buffer) overflow attacks on 64 bit + platforms like amd64. + - pdftops/Xref.cxx: fix several unchecked negative integer conditions + * Thanks to Marcus Meissner <meissner@suse.de> for providing the patches. + + -- Martin Pitt <mpitt@debian.org> Mon, 1 Nov 2004 14:37:58 +0100 + cupsys (1.1.20final+rc1-10ubuntu2) hoary; urgency=low * Fixed debian/patches/ubuntu-localports.patch: do not comment out the diff -u cupsys-1.1.20final+rc1/debian/patches/36pdftopsoverflow.patch cupsys-1.1.20final+rc1/debian/patches/36pdftopsoverflow.patch --- cupsys-1.1.20final+rc1/debian/patches/36pdftopsoverflow.patch +++ cupsys-1.1.20final+rc1/debian/patches/36pdftopsoverflow.patch @@ -1,6 +1,6 @@ ---- cupsys-1.1.14.orig/pdftops/Catalog.cxx +--- cupsys-1.1.14/pdftops/Catalog.cxx +++ cupsys-1.1.14/pdftops/Catalog.cxx -@@ -20,6 +20,7 @@ +@@ -22,6 +22,7 @@ #include "Error.h" #include "Link.h" #include "Catalog.h" @@ -8,9 +8,9 @@ //------------------------------------------------------------------------ // Catalog -@@ -61,6 +62,12 @@ +@@ -64,6 +65,12 @@ } - pagesSize = numPages0 = obj.getInt(); + pagesSize = numPages0 = (int)obj.getNum(); obj.free(); + if ((pagesSize >= INT_MAX / sizeof(Page *)) || + (pagesSize >= INT_MAX / sizeof(Ref))) { @@ -21,7 +21,7 @@ pages = (Page **)gmalloc(pagesSize * sizeof(Page *)); pageRefs = (Ref *)gmalloc(pagesSize * sizeof(Ref)); for (i = 0; i < pagesSize; ++i) { -@@ -153,6 +160,11 @@ +@@ -191,6 +198,11 @@ } if (start >= pagesSize) { pagesSize += 32; @@ -33,51 +33,157 @@ pages = (Page **)grealloc(pages, pagesSize * sizeof(Page *)); pageRefs = (Ref *)grealloc(pageRefs, pagesSize * sizeof(Ref)); for (j = pagesSize - 32; j < pagesSize; ++j) { ---- cupsys-1.1.14.orig/pdftops/XRef.cxx -+++ cupsys-1.1.14/pdftops/XRef.cxx -@@ -25,6 +25,7 @@ +--- cupsys-1.1.14/pdftops/gmem.c ++++ cupsys-1.1.14/pdftops/gmem.c +@@ -53,9 +53,9 @@ + + #endif /* DEBUG_MEM */ + +-void *gmalloc(int size) { ++void *gmalloc(size_t size) { + #ifdef DEBUG_MEM +- int size1; ++ size_t size1; + char *mem; + GMemHdr *hdr; + void *data; +@@ -94,11 +94,11 @@ #endif + } + +-void *grealloc(void *p, int size) { ++void *grealloc(void *p, size_t size) { + #ifdef DEBUG_MEM + GMemHdr *hdr; + void *q; +- int oldSize; ++ size_t oldSize; + + if (size == 0) { + if (p) +@@ -137,7 +137,7 @@ + + void gfree(void *p) { + #ifdef DEBUG_MEM +- int size; ++ size_t size; + GMemHdr *hdr; + GMemHdr *prevHdr, *q; + int lst; +--- cupsys-1.1.14/pdftops/gmem.h ++++ cupsys-1.1.214/pdftops/gmem.h +@@ -19,13 +19,13 @@ + * Same as malloc, but prints error message and exits if malloc() + * returns NULL. + */ +-extern void *gmalloc(int size); ++extern void *gmalloc(size_t size); + + /* + * Same as realloc, but prints error message and exits if realloc() + * returns NULL. If <p> is NULL, calls malloc instead of realloc(). + */ +-extern void *grealloc(void *p, int size); ++extern void *grealloc(void *p, size_t size); + + /* + * Same as free, but checks for and ignores NULL pointers. +--- cupsys-1.1.14/pdftops/XRef.cxx ++++ cupsys-1.1.14/pdftops/XRef.cxx +@@ -28,6 +28,7 @@ #include "Error.h" + #include "ErrorCodes.h" #include "XRef.h" +#include <limits.h> //------------------------------------------------------------------------ -@@ -71,6 +72,11 @@ +@@ -66,6 +67,8 @@ + start = str->getStart(); + pos = readTrailer(); + ++ entries = NULL; ++ + // if there was a problem with the trailer, + // try to reconstruct the xref table + if (pos == 0) { +@@ -76,6 +79,11 @@ // trailer is ok - read the xref table } else { -+ if ( size >= INT_MAX/sizeof(XRefEntry)) { ++ if (size < 0 || size >= INT_MAX/sizeof(XRefEntry)) { + error(-1, "Invalid 'size' inside xref table."); + ok = gFalse; + return; + } entries = (XRefEntry *)gmalloc(size * sizeof(XRefEntry)); for (i = 0; i < size; ++i) { - entries[i].offset = -1; -@@ -258,6 +264,10 @@ + entries[i].offset = 0xffffffff; +@@ -182,7 +190,7 @@ + n = atoi(p); + while ('0' <= *p && *p <= '9') ++p; + while (isspace(*p)) ++p; +- if (p == buf) { ++ if (n < 0 || p == buf) { + goto err1; + } + pos1 += (p - buf) + n * 20; +@@ -267,6 +275,10 @@ + } + s[i] = '\0'; + first = atoi(s); ++ if (first < 0) { ++ error(-1, "Invalid 'first'"); ++ goto err2; ++ } + while ((c = str->lookChar()) != EOF && isspace(c)) { + str->getChar(); + } +@@ -278,6 +290,10 @@ + } + s[i] = '\0'; + n = atoi(s); ++ if (n<=0) { ++ error(-1, "Invalid 'n'"); ++ goto err2; ++ } + while ((c = str->lookChar()) != EOF && isspace(c)) { + str->getChar(); + } +@@ -285,6 +301,10 @@ // table size if (first + n > size) { newSize = first + n; -+ if (newSize >= INT_MAX/sizeof(XRefEntry)) { ++ if (newSize < 0 || newSize >= INT_MAX/sizeof(XRefEntry)) { + error(-1, "Invalid 'newSize'"); + goto err2; + } entries = (XRefEntry *)grealloc(entries, newSize * sizeof(XRefEntry)); for (i = size; i < newSize; ++i) { entries[i].offset = 0xffffffff; -@@ -399,6 +409,10 @@ +@@ -416,6 +436,10 @@ + // look for object + } else if (isdigit(*p)) { + num = atoi(p); ++ if (num < 0) { ++ error(-1, "Invalid 'num' parameters."); ++ return gFalse; ++ } + do { + ++p; + } while (*p && isdigit(*p)); +@@ -435,6 +459,10 @@ if (!strncmp(p, "obj", 3)) { if (num >= size) { newSize = (num + 1 + 255) & ~255; -+ if (newSize >= INT_MAX / sizeof(XRefEntry)) { ++ if (newSize < 0 || newSize >= INT_MAX / sizeof(XRefEntry)) { + error(-1, "Invalid 'obj' parameters."); + return gFalse; + } entries = (XRefEntry *) grealloc(entries, newSize * sizeof(XRefEntry)); for (i = size; i < newSize; ++i) { -@@ -420,6 +434,10 @@ +@@ -456,6 +484,10 @@ } else if (!strncmp(p, "endstream", 9)) { if (streamEndsLen == streamEndsSize) { streamEndsSize += 64; @@ -89,3 +195,2 @@ - streamEndsSize * sizeof(int)); + streamEndsSize * sizeof(int)); } - streamEnds[streamEndsLen++] = pos;
diff -u tetex-bin-2.0.2/debian/rules tetex-bin-2.0.2/debian/rules --- tetex-bin-2.0.2/debian/rules +++ tetex-bin-2.0.2/debian/rules @@ -47,6 +47,8 @@ patch -p1 -Ni debian/patches/patch-texdoc patch -p1 -NRi debian/patches/patch-tmp || true patch -p1 -Ni debian/patches/patch-tmp + patch -p1 -NRi debian/patches/patch-more-CAN-2004-0888 || true + patch -p1 -Ni debian/patches/patch-more-CAN-2004-0888 cp -f /usr/share/misc/config.guess /usr/share/misc/config.sub ./texk/ cp -f /usr/share/misc/config.guess /usr/share/misc/config.sub ./utils/texinfo/ cp -f /usr/share/misc/config.guess /usr/share/misc/config.sub ./config/ @@ -85,6 +87,7 @@ # Add here commands to clean up after the build process. # Make sure all of our expected symlinks are in place sh debian/restore-symlinks + patch -p1 -NRi debian/patches/patch-more-CAN-2004-0888 || true patch -p1 -NRi debian/patches/patch-tmp || true patch -p1 -NRi debian/patches/patch-deb || true patch -p1 -NRi debian/patches/patch-src || true diff -u tetex-bin-2.0.2/debian/changelog tetex-bin-2.0.2/debian/changelog --- tetex-bin-2.0.2/debian/changelog +++ tetex-bin-2.0.2/debian/changelog @@ -1,3 +1,19 @@ +tetex-bin (2.0.2-23ubuntu1) hoary; urgency=low + + * SECURITY UPDATE: more buffer overflows in xpdf library + * Fixed more integer overflows discovered by Markus Meissner + <meissner@suse.de>, thanks to him for discovering this. + * Added debian/patches/patch-more-CAN-2004-0888: + - libs/xpdf/goo/gmem.[ch]: change declarations of gmalloc and grealloc to + use size_t instead of int; int truncated sizes to 32 bits, which made + xpdf still vulnerable to integer (and eventually buffer) overflow + attacks on 64 bit platforms like amd64. + - libs/xpdf/xpdf/XRef.cc: fix several unchecked negative integer conditions + * References: + CAN-2004-0888 + + -- Martin Pitt <mpitt@debian.org> Mon, 1 Nov 2004 15:14:34 +0100 + tetex-bin (2.0.2-23) unstable; urgency=high * Security fix for the xpdf code included in pdftex. Many thanks to only in patch2: unchanged: --- tetex-bin-2.0.2.orig/debian/patches/patch-more-CAN-2004-0888 +++ tetex-bin-2.0.2/debian/patches/patch-more-CAN-2004-0888 @@ -0,0 +1,138 @@ +diff -Nur tetex-bin-2.0.2/libs/xpdf/goo/gmem.c tetex-bin-2.0.2.new/libs/xpdf/goo/gmem.c +--- tetex-bin-2.0.2/libs/xpdf/goo/gmem.c 2002-11-03 23:15:36.000000000 +0100 ++++ tetex-bin-2.0.2.new/libs/xpdf/goo/gmem.c 2004-11-01 15:09:05.303145312 +0100 +@@ -53,9 +53,9 @@ + + #endif /* DEBUG_MEM */ + +-void *gmalloc(int size) { ++void *gmalloc(size_t size) { + #ifdef DEBUG_MEM +- int size1; ++ size_t size1; + char *mem; + GMemHdr *hdr; + void *data; +@@ -94,11 +94,11 @@ + #endif + } + +-void *grealloc(void *p, int size) { ++void *grealloc(void *p, size_t size) { + #ifdef DEBUG_MEM + GMemHdr *hdr; + void *q; +- int oldSize; ++ size_t oldSize; + + if (size == 0) { + if (p) +@@ -137,7 +137,7 @@ + + void gfree(void *p) { + #ifdef DEBUG_MEM +- int size; ++ size_t size; + GMemHdr *hdr; + GMemHdr *prevHdr, *q; + int lst; +diff -Nur tetex-bin-2.0.2/libs/xpdf/goo/gmem.h tetex-bin-2.0.2.new/libs/xpdf/goo/gmem.h +--- tetex-bin-2.0.2/libs/xpdf/goo/gmem.h 2002-11-03 23:15:36.000000000 +0100 ++++ tetex-bin-2.0.2.new/libs/xpdf/goo/gmem.h 2004-11-01 15:09:05.363136192 +0100 +@@ -19,13 +19,13 @@ + * Same as malloc, but prints error message and exits if malloc() + * returns NULL. + */ +-extern void *gmalloc(int size); ++extern void *gmalloc(size_t size); + + /* + * Same as realloc, but prints error message and exits if realloc() + * returns NULL. If <p> is NULL, calls malloc instead of realloc(). + */ +-extern void *grealloc(void *p, int size); ++extern void *grealloc(void *p, size_t size); + + /* + * Same as free, but checks for and ignores NULL pointers. +diff -Nur tetex-bin-2.0.2/libs/xpdf/xpdf/XRef.cc tetex-bin-2.0.2.new/libs/xpdf/xpdf/XRef.cc +--- tetex-bin-2.0.2/libs/xpdf/xpdf/XRef.cc 2004-11-01 15:08:42.263647848 +0100 ++++ tetex-bin-2.0.2.new/libs/xpdf/xpdf/XRef.cc 2004-11-01 15:10:01.625583000 +0100 +@@ -67,6 +67,8 @@ + start = str->getStart(); + pos = readTrailer(); + ++ entries = NULL; ++ + // if there was a problem with the trailer, + // try to reconstruct the xref table + if (pos == 0) { +@@ -77,7 +79,7 @@ + + // trailer is ok - read the xref table + } else { +- if (size >= INT_MAX/sizeof(XRefEntry)) { ++ if (size < 0 || size >= INT_MAX/sizeof(XRefEntry)) { + error(-1, "Invalid 'size' inside xref table."); + ok = gFalse; + errCode = errDamaged; +@@ -182,7 +184,7 @@ + n = atoi(p); + while ('0' <= *p && *p <= '9') ++p; + while (isspace(*p)) ++p; +- if (p == buf) ++ if ((p == buf) || (n < 0)) /* must make progress */ + return 0; + pos1 += (p - buf) + n * 20; + } +@@ -256,6 +258,10 @@ + } + s[i] = '\0'; + first = atoi(s); ++ if (first < 0) { ++ error(-1, "Invalid 'first'"); ++ goto err2; ++ } + while ((c = str->lookChar()) != EOF && isspace(c)) { + str->getChar(); + } +@@ -267,6 +273,10 @@ + } + s[i] = '\0'; + n = atoi(s); ++ if (n<=0) { ++ error(-1, "Invalid 'n'"); ++ goto err2; ++ } + while ((c = str->lookChar()) != EOF && isspace(c)) { + str->getChar(); + } +@@ -274,7 +284,7 @@ + // table size + if (first + n > size) { + newSize = size + 256; +- if (newSize >= INT_MAX/sizeof(XRefEntry)) { ++ if (newSize < 0 || newSize >= INT_MAX/sizeof(XRefEntry)) { + error(-1, "Invalid 'newSize'"); + goto err2; + } +@@ -402,6 +412,10 @@ + // look for object + } else if (isdigit(*p)) { + num = atoi(p); ++ if (num < 0) { ++ error(-1, "Invalid 'num' parameters."); ++ return gFalse; ++ } + do { + ++p; + } while (*p && isdigit(*p)); +@@ -421,7 +435,7 @@ + if (!strncmp(p, "obj", 3)) { + if (num >= size) { + newSize = (num + 1 + 255) & ~255; +- if (newSize >= INT_MAX/sizeof(XRefEntry)) { ++ if (newSize < 0 || newSize >= INT_MAX/sizeof(XRefEntry)) { + error(-1, "Invalid 'obj' parameters."); + return gFalse; + }
Attachment:
signature.asc
Description: Digital signature