CVE-2014-0210: unvalidated length fields in fs_read_glyphs()

fs_read_glyphs() parses a reply from the font server.  The reply
contains embedded length fields, none of which are validated.
This can cause out of bound reads when looping over the glyph
bitmaps in the reply.

Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Reviewed-by: Matthieu Herrb <matthieu@herrb.eu>
This commit is contained in:
Alan Coopersmith
2014-04-25 23:03:24 -07:00
parent a3f2142153
commit 5206836525

View File

@@ -1907,6 +1907,7 @@ fs_read_glyphs(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
FontInfoPtr pfi = &pfont->info;
fsQueryXBitmaps16Reply *rep;
char *buf;
long bufleft; /* length of reply left to use */
fsOffset32 *ppbits;
fsOffset32 local_off;
char *off_adr;
@@ -1938,9 +1939,33 @@ fs_read_glyphs(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
buf = (char *) rep;
buf += SIZEOF (fsQueryXBitmaps16Reply);
bufleft = rep->length << 2;
bufleft -= SIZEOF (fsQueryXBitmaps16Reply);
if ((bufleft / SIZEOF (fsOffset32)) < rep->num_chars)
{
#ifdef DEBUG
fprintf(stderr,
"fsQueryXBitmaps16: num_chars (%d) > bufleft (%ld) / %d\n",
rep->num_chars, bufleft, SIZEOF (fsOffset32));
#endif
err = AllocError;
goto bail;
}
ppbits = (fsOffset32 *) buf;
buf += SIZEOF (fsOffset32) * (rep->num_chars);
bufleft -= SIZEOF (fsOffset32) * (rep->num_chars);
if (bufleft < rep->nbytes)
{
#ifdef DEBUG
fprintf(stderr,
"fsQueryXBitmaps16: nbytes (%d) > bufleft (%ld)\n",
rep->nbytes, bufleft);
#endif
err = AllocError;
goto bail;
}
pbitmaps = (pointer ) buf;
if (blockrec->type == FS_LOAD_GLYPHS)
@@ -1998,7 +2023,9 @@ fs_read_glyphs(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
*/
if (NONZEROMETRICS(&fsdata->encoding[minchar].metrics))
{
if (local_off.length)
if (local_off.length &&
(local_off.position < rep->nbytes) &&
(local_off.length <= (rep->nbytes - local_off.position)))
{
bits = allbits;
allbits += local_off.length;