aboutsummaryrefslogtreecommitdiffstats
path: root/main/libxfont/0011-CVE-2014-0210-unvalidated-length-fields-in-fs_read_l.patch
blob: 54abe8766d57c23d2d398c7c828c670a1eceefbe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
From 5fa73ac18474be3032ee7af9c6e29deab163ea39 Mon Sep 17 00:00:00 2001
From: Alan Coopersmith <alan.coopersmith@oracle.com>
Date: Fri, 2 May 2014 19:24:17 -0700
Subject: [PATCH 11/12] CVE-2014-0210: unvalidated length fields in
 fs_read_list()

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

Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
---
 src/fc/fserve.c |   15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/src/fc/fserve.c b/src/fc/fserve.c
index 581bb1b..4dcdc04 100644
--- a/src/fc/fserve.c
+++ b/src/fc/fserve.c
@@ -2355,6 +2355,7 @@ fs_read_list(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
     FSBlockedListPtr	blist = (FSBlockedListPtr) blockrec->data;
     fsListFontsReply	*rep;
     char		*data;
+    long		dataleft; /* length of reply left to use */
     int			length,
 			i,
 			ret;
@@ -2372,16 +2373,30 @@ fs_read_list(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
 	return AllocError;
     }
     data = (char *) rep + SIZEOF (fsListFontsReply);
+    dataleft = (rep->length << 2) - SIZEOF (fsListFontsReply);
 
     err = Successful;
     /* copy data into FontPathRecord */
     for (i = 0; i < rep->nFonts; i++)
     {
+	if (dataleft < 1)
+	    break;
 	length = *(unsigned char *)data++;
+	dataleft--; /* used length byte */
+	if (length > dataleft) {
+#ifdef DEBUG
+	    fprintf(stderr,
+		    "fsListFonts: name length (%d) > dataleft (%ld)\n",
+		    length, dataleft);
+#endif
+	    err = BadFontName;
+	    break;
+	}
 	err = AddFontNamesName(blist->names, data, length);
 	if (err != Successful)
 	    break;
 	data += length;
+	dataleft -= length;
     }
     _fs_done_read (conn, rep->length << 2);
     return err;
-- 
1.7.10