aboutsummaryrefslogtreecommitdiff
path: root/debian/patches/1011-CVE-2014-0210-unvalidated-length-fields-in-fs_r.full.patch
blob: 9d0f3f875316ba7e0275808b25654daef987e464 (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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
From e29bbd5bf0565eaf7c02f85a57b87f66531fa6b3 Mon Sep 17 00:00:00 2001
From: Mike DePaulo <mikedep333@gmail.com>
Date: Sun, 8 Feb 2015 22:08:09 -0500
Subject: [PATCH 11/40] CVE-2014-0210: unvalidated length fields in
 fs_read_query_info() from xorg/lib/libXfont commit
 491291cabf78efdeec8f18b09e14726a9030cc8f

fs_read_query_info() 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 in either fs_read_query_info() or in
_fs_convert_props() which it calls to parse the fsPropInfo in the reply.

v2: apply correctly on nx-libs 3.6.x (Mihai Moldovan)
---
 nx-X11/lib/font/fc/fsconvert.c | 19 ++++++++++++++-----
 nx-X11/lib/font/fc/fserve.c    | 43 +++++++++++++++++++++++++++++++++++++++---
 2 files changed, 54 insertions(+), 8 deletions(-)

diff --git a/nx-X11/lib/font/fc/fsconvert.c b/nx-X11/lib/font/fc/fsconvert.c
index 9a5e194..afa2c32 100644
--- a/nx-X11/lib/font/fc/fsconvert.c
+++ b/nx-X11/lib/font/fc/fsconvert.c
@@ -123,6 +123,10 @@ _fs_convert_props(fsPropInfo *pi, fsPropOffset *po, pointer pd,
     for (i = 0; i < nprops; i++, dprop++, is_str++) 
     {
 	memcpy(&local_off, off_adr, SIZEOF(fsPropOffset));
+	if ((local_off.name.position >= pi->data_len) ||
+		(local_off.name.length >
+		 (pi->data_len - local_off.name.position)))
+	    goto bail;
 	dprop->name = MakeAtom(&pdc[local_off.name.position],
 			       local_off.name.length, 1);
 	if (local_off.type != PropTypeString) {
@@ -130,15 +134,20 @@ _fs_convert_props(fsPropInfo *pi, fsPropOffset *po, pointer pd,
 	    dprop->value = local_off.value.position;
 	} else {
 	    *is_str = TRUE;
+	    if ((local_off.value.position >= pi->data_len) ||
+			(local_off.value.length >
+			 (pi->data_len - local_off.value.position)))
+			goto bail;
 	    dprop->value = (INT32) MakeAtom(&pdc[local_off.value.position],
 					    local_off.value.length, 1);
 	    if (dprop->value == BAD_RESOURCE)
 	    {
-		xfree (pfi->props);
-		pfi->nprops = 0;
-		pfi->props = 0;
-		pfi->isStringProp = 0;
-		return -1;
+		  bail:
+			xfree (pfi->props);
+			pfi->nprops = 0;
+			pfi->props = 0;
+			pfi->isStringProp = 0;
+			return -1;
 	    }
 	}
 	off_adr += SIZEOF(fsPropOffset);
diff --git a/nx-X11/lib/font/fc/fserve.c b/nx-X11/lib/font/fc/fserve.c
index 9e652d2..75cabdd 100644
--- a/nx-X11/lib/font/fc/fserve.c
+++ b/nx-X11/lib/font/fc/fserve.c
@@ -866,6 +866,7 @@ fs_read_query_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
     FSFpePtr		conn = (FSFpePtr) fpe->private;
     fsQueryXInfoReply	*rep;
     char		*buf;
+    long		bufleft = 0; /* length of reply left to use */
     fsPropInfo		*pi;
     fsPropOffset	*po;
     pointer		pd;
@@ -896,7 +897,10 @@ fs_read_query_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
 
     buf = (char *) rep;
     buf += SIZEOF(fsQueryXInfoReply);
-    
+ 
+    bufleft = rep->length << 2;
+    bufleft -= SIZEOF(fsQueryXInfoReply);
+
     /* move the data over */
     fsUnpack_XFontInfoHeader(rep, pInfo);
     
@@ -904,19 +908,52 @@ fs_read_query_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
     _fs_init_fontinfo(conn, pInfo);
 
     /* Compute offsets into the reply */
+    if (bufleft < SIZEOF(fsPropInfo))
+    {
+	ret = -1;
+#ifdef DEBUG
+	fprintf(stderr, "fsQueryXInfo: bufleft (%ld) < SIZEOF(fsPropInfo)\n",
+		bufleft);
+#endif
+	goto bail;
+    }
     pi = (fsPropInfo *) buf;
     buf += SIZEOF (fsPropInfo);
-    
+    bufleft -= SIZEOF (fsPropInfo);
+
+    if ((bufleft / SIZEOF (fsPropOffset)) < pi->num_offsets)
+    {
+	ret = -1;
+#ifdef DEBUG
+	fprintf(stderr,
+		"fsQueryXInfo: (bufleft / SIZEOF (fsPropOffset)) (%ld) < pi->num_offsets (%d)\n",
+		bufleft / SIZEOF (fsPropOffset), pi->num_offsets);
+#endif
+	goto bail;
+    }
     po = (fsPropOffset *) buf;
     buf += pi->num_offsets * SIZEOF(fsPropOffset);
+    bufleft -= pi->num_offsets * SIZEOF(fsPropOffset);
 
+    if (bufleft < pi->data_len)
+    {
+	ret = -1;
+#ifdef DEBUG
+	fprintf(stderr,
+		"fsQueryXInfo: bufleft (%ld) < data_len (%d)\n",
+		bufleft, pi->data_len);
+#endif
+	goto bail;
+    }
     pd = (pointer) buf;
     buf += pi->data_len;
+    bufleft -= pi->data_len;
     
     /* convert the properties and step over the reply */
     ret = _fs_convert_props(pi, po, pd, pInfo);
+  bail:    
     _fs_done_read (conn, rep->length << 2);
-    
+
     if (ret == -1)
     {
 	fs_cleanup_bfont (bfont);
-- 
2.1.4