--- wv-1.2.0/lfo.c.cve-2006-4513 2006-11-06 16:12:40.000000000 -0700 +++ wv-1.2.0/lfo.c 2006-11-06 16:13:02.000000000 -0700 @@ -32,6 +32,16 @@ one has (LFO.clfolvl), and writes out, i followed by its corresponding LVL structure (if LFOLVL.fFormatting is set). */ +static int +multiplication_will_overflow(U32 a, U32 b) +{ + if((a > 0) && (b > 0) && (G_MAXUINT / a) >= b) { + return 0; + } + + return 1; +} + int wvGetLFO_records (LFO ** lfo, LFOLVL ** lfolvl, LVL ** lvl, U32 * nolfo, U32 * nooflvl, U32 offset, U32 len, wvStream * fd) @@ -49,7 +59,9 @@ wvGetLFO_records (LFO ** lfo, LFOLVL ** wvTrace (("pos %x %d\n", wvStream_tell (fd), *nooflvl)); wvTrace (("nolfo is %d nooflvl is %d\n", *nolfo, *nooflvl)); - if (*nooflvl == 0) + if ((*nooflvl == 0) || + multiplication_will_overflow(sizeof (LFOLVL), *nooflvl) || + multiplication_will_overflow(sizeof (LVL), *nooflvl)) { *lfolvl = NULL; *lvl = NULL; @@ -101,17 +113,23 @@ wvGetLFO_PLF (LFO ** lfo, U32 * nolfo, U *nolfo = read_32ubit (fd); wvTrace (("%d\n", *nolfo)); + /* check for integer overflow */ + if (multiplication_will_overflow(*nolfo, sizeof(LFO))) { + wvError (("Malicious document!\n")); + *nolfo = 0; + return (1); + } else { *lfo = (LFO *) wvMalloc (*nolfo * sizeof (LFO)); if (*lfo == NULL) { - wvError ( - ("NO MEM 1, failed to alloc %d bytes\n", + wvError (("NO MEM 1, failed to alloc %d bytes\n", *nolfo * sizeof (LFO))); return (1); } for (i = 0; i < *nolfo; i++) wvGetLFO (&((*lfo)[i]), fd); } + } return (0); }