CESA-2004-007 - rev 1 xpdf-2.03 example integer overflow and integer arithmetic flaws =============================================================== Programs affected: xpdf, gpdf and kpdf. Severity: Unassessed. This advisory lists code flaws discovered by inspection of the xpdf-2.03 code. Note that the GNOME and KDE PDF browsers seem to be based on xpdf. This advisory follows on from CESA-2004-002, which looked at xpdf-3.0. In response to feedback, xpdf-2.03 was briefly examined. The reason for this is that xpdf-2.03 and derivatives are currently very common. For example, kpdf in all released versions is based on xpdf-2 (this may change with KDE 3.3.1). Flaw 1. Multiple integer overflows possible when allocating memory. For example, XRef.cc: 79 entries = (XRefEntry *)gmalloc(size * sizeof(XRefEntry)); "size" is an arbitrary signed int and comes from the PDF. XRef.cc: 286 if (first + n > size) { newSize = first + n; entries = (XRefEntry *)grealloc(entries, newSize * sizeof(XRefEntry)); "first" and "n" are arbitrary signed ints and come from the PDF. Not only might the addition overflow, but also games can be played by makking one or both negative. After the addition, the multiplication for thr grealloc() might overflow. Catalog.cc:68 pages = (Page **)gmalloc(pagesSize * sizeof(Page *)); pageRefs = (Ref *)gmalloc(pagesSize * sizeof(Ref)); "pageSize" is an arbitrary signed int from the PDF. Demo PDF: http://scary.beasts.org/misc/bad5.pdf Flaw 2. Integer overflows leading to out of bounds write. XRef.cc:436 if (num >= size) { newSize = (num + 1 + 255) & ~255; entries = (XRefEntry *) grealloc(entries, newSize * sizeof(XRefEntry)); for (i = size; i < newSize; ++i) { entries[i].offset = 0xffffffff; entries[i].used = gFalse; } size = newSize; } if (!entries[num].used || gen >= entries[num].gen) { entries[num].offset = pos - start; entries[num].gen = gen; entries[num].used = gTrue; } "num" and "gen" are arbitrary signed ints from the PDF file. This causes a problem with integer overflow on the memory allocation. But more seriously, a negative value of "num" leads (with minor restrictions) to an out of bounds write to the heap[*]. One of the values written is "gen" - an arbitrary int from the PDF file. [*] - with a sufficiently negative value of "num", I don't see why the write access couldn't be so out of bounds that it in fact writes into the stack. Demo PDF: http://scary.beasts.org/misc/bad4.pdf CESA-2004-007 - rev 1 Chris Evans chris@scary.beasts.org [Advertisement: I am interested in moving into a security related field full-time. E-mail me to discuss.]