summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Coopersmith <alan.coopersmith@oracle.com>2014-04-25 23:03:24 -0700
committerAlan Coopersmith <alan.coopersmith@oracle.com>2014-05-13 08:29:30 -0700
commit2b7b6f21ec67c2e4fdc3cee9db3199a6edef5c5c (patch)
treea73d55b41e3fde8f88b949229ca61013b3194d0b
parent573c3fdcb934ca1f3243f6ced40e1f037ea6cefe (diff)
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> (cherry picked from commit 520683652564c2a4e42328ae23eef9bb63271565)
-rw-r--r--src/fc/fserve.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/src/fc/fserve.c b/src/fc/fserve.c
index f7cd3b1..076515c 100644
--- a/src/fc/fserve.c
+++ b/src/fc/fserve.c
@@ -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;