Blame SOURCES/0010-CVE-2014-0210-unvalidated-length-fields-in-fs_read_g.patch

cf1e18
From 520683652564c2a4e42328ae23eef9bb63271565 Mon Sep 17 00:00:00 2001
cf1e18
From: Alan Coopersmith <alan.coopersmith@oracle.com>
cf1e18
Date: Fri, 25 Apr 2014 23:03:24 -0700
cf1e18
Subject: [PATCH 10/12] CVE-2014-0210: unvalidated length fields in fs_read_glyphs()
cf1e18
cf1e18
fs_read_glyphs() parses a reply from the font server.  The reply
cf1e18
contains embedded length fields, none of which are validated.
cf1e18
This can cause out of bound reads when looping over the glyph
cf1e18
bitmaps in the reply.
cf1e18
cf1e18
Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
cf1e18
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
cf1e18
Reviewed-by: Adam Jackson <ajax@redhat.com>
cf1e18
Reviewed-by: Matthieu Herrb <matthieu@herrb.eu>
cf1e18
---
cf1e18
 src/fc/fserve.c |   29 ++++++++++++++++++++++++++++-
cf1e18
 1 files changed, 28 insertions(+), 1 deletions(-)
cf1e18
cf1e18
diff --git a/src/fc/fserve.c b/src/fc/fserve.c
cf1e18
index 232e969..581bb1b 100644
cf1e18
--- a/src/fc/fserve.c
cf1e18
+++ b/src/fc/fserve.c
cf1e18
@@ -1907,6 +1907,7 @@ fs_read_glyphs(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
cf1e18
     FontInfoPtr		    pfi = &pfont->info;
cf1e18
     fsQueryXBitmaps16Reply  *rep;
cf1e18
     char		    *buf;
cf1e18
+    long		    bufleft; /* length of reply left to use */
cf1e18
     fsOffset32		    *ppbits;
cf1e18
     fsOffset32		    local_off;
cf1e18
     char		    *off_adr;
cf1e18
@@ -1938,9 +1939,33 @@ fs_read_glyphs(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
cf1e18
     buf = (char *) rep;
cf1e18
     buf += SIZEOF (fsQueryXBitmaps16Reply);
cf1e18
 
cf1e18
+    bufleft = rep->length << 2;
cf1e18
+    bufleft -= SIZEOF (fsQueryXBitmaps16Reply);
cf1e18
+
cf1e18
+    if ((bufleft / SIZEOF (fsOffset32)) < rep->num_chars)
cf1e18
+    {
cf1e18
+#ifdef DEBUG
cf1e18
+	fprintf(stderr,
cf1e18
+		"fsQueryXBitmaps16: num_chars (%d) > bufleft (%ld) / %d\n",
cf1e18
+		rep->num_chars, bufleft, SIZEOF (fsOffset32));
cf1e18
+#endif
cf1e18
+	err = AllocError;
cf1e18
+	goto bail;
cf1e18
+    }
cf1e18
     ppbits = (fsOffset32 *) buf;
cf1e18
     buf += SIZEOF (fsOffset32) * (rep->num_chars);
cf1e18
+    bufleft -= SIZEOF (fsOffset32) * (rep->num_chars);
cf1e18
 
cf1e18
+    if (bufleft < rep->nbytes)
cf1e18
+    {
cf1e18
+#ifdef DEBUG
cf1e18
+	fprintf(stderr,
cf1e18
+		"fsQueryXBitmaps16: nbytes (%d) > bufleft (%ld)\n",
cf1e18
+		rep->nbytes, bufleft);
cf1e18
+#endif
cf1e18
+	err = AllocError;
cf1e18
+	goto bail;
cf1e18
+    }
cf1e18
     pbitmaps = (pointer ) buf;
cf1e18
 
cf1e18
     if (blockrec->type == FS_LOAD_GLYPHS)
cf1e18
@@ -1998,7 +2023,9 @@ fs_read_glyphs(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
cf1e18
 	     */
cf1e18
 	    if (NONZEROMETRICS(&fsdata->encoding[minchar].metrics))
cf1e18
 	    {
cf1e18
-		if (local_off.length)
cf1e18
+		if (local_off.length &&
cf1e18
+		    (local_off.position < rep->nbytes) &&
cf1e18
+		    (local_off.length <= (rep->nbytes - local_off.position)))
cf1e18
 		{
cf1e18
 		    bits = allbits;
cf1e18
 		    allbits += local_off.length;
cf1e18
-- 
cf1e18
1.7.1
cf1e18