Blame SOURCES/0011-CVE-2014-0210-unvalidated-length-fields-in-fs_read_l.patch

cf1e18
From 5fa73ac18474be3032ee7af9c6e29deab163ea39 Mon Sep 17 00:00:00 2001
cf1e18
From: Alan Coopersmith <alan.coopersmith@oracle.com>
cf1e18
Date: Fri, 2 May 2014 19:24:17 -0700
cf1e18
Subject: [PATCH 11/12] CVE-2014-0210: unvalidated length fields in fs_read_list()
cf1e18
cf1e18
fs_read_list() parses a reply from the font server.  The reply
cf1e18
contains a list of strings with embedded length fields, none of
cf1e18
which are validated. This can cause out of bound reads when looping
cf1e18
over the strings in the reply.
cf1e18
cf1e18
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
cf1e18
---
cf1e18
 src/fc/fserve.c |   15 +++++++++++++++
cf1e18
 1 files changed, 15 insertions(+), 0 deletions(-)
cf1e18
cf1e18
diff --git a/src/fc/fserve.c b/src/fc/fserve.c
cf1e18
index 581bb1b..4dcdc04 100644
cf1e18
--- a/src/fc/fserve.c
cf1e18
+++ b/src/fc/fserve.c
cf1e18
@@ -2355,6 +2355,7 @@ fs_read_list(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
cf1e18
     FSBlockedListPtr	blist = (FSBlockedListPtr) blockrec->data;
cf1e18
     fsListFontsReply	*rep;
cf1e18
     char		*data;
cf1e18
+    long		dataleft; /* length of reply left to use */
cf1e18
     int			length,
cf1e18
 			i,
cf1e18
 			ret;
cf1e18
@@ -2372,16 +2373,30 @@ fs_read_list(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
cf1e18
 	return AllocError;
cf1e18
     }
cf1e18
     data = (char *) rep + SIZEOF (fsListFontsReply);
cf1e18
+    dataleft = (rep->length << 2) - SIZEOF (fsListFontsReply);
cf1e18
 
cf1e18
     err = Successful;
cf1e18
     /* copy data into FontPathRecord */
cf1e18
     for (i = 0; i < rep->nFonts; i++)
cf1e18
     {
cf1e18
+	if (dataleft < 1)
cf1e18
+	    break;
cf1e18
 	length = *(unsigned char *)data++;
cf1e18
+	dataleft--; /* used length byte */
cf1e18
+	if (length > dataleft) {
cf1e18
+#ifdef DEBUG
cf1e18
+	    fprintf(stderr,
cf1e18
+		    "fsListFonts: name length (%d) > dataleft (%ld)\n",
cf1e18
+		    length, dataleft);
cf1e18
+#endif
cf1e18
+	    err = BadFontName;
cf1e18
+	    break;
cf1e18
+	}
cf1e18
 	err = AddFontNamesName(blist->names, data, length);
cf1e18
 	if (err != Successful)
cf1e18
 	    break;
cf1e18
 	data += length;
cf1e18
+	dataleft -= length;
cf1e18
     }
cf1e18
     _fs_done_read (conn, rep->length << 2);
cf1e18
     return err;
cf1e18
-- 
cf1e18
1.7.1
cf1e18