aboutsummaryrefslogtreecommitdiff
path: root/debian/patches/1011-CVE-2014-0210-unvalidated-length-fields-in-fs_r.full.patch
blob: 9a75a01c8bd6cf5c8dd8d1fb035950bfc49bf678 (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
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(-)

--- 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, fsProp
     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, fsProp
 	    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);
--- a/nx-X11/lib/font/fc/fserve.c
+++ b/nx-X11/lib/font/fc/fserve.c
@@ -865,6 +865,7 @@ fs_read_query_info(FontPathElementPtr fp
     FSFpePtr		conn = (FSFpePtr) fpe->private;
     fsQueryXInfoReply	*rep;
     char		*buf;
+    long		bufleft = 0; /* length of reply left to use */
     fsPropInfo		*pi;
     fsPropOffset	*po;
     pointer		pd;
@@ -895,7 +896,10 @@ fs_read_query_info(FontPathElementPtr fp
 
     buf = (char *) rep;
     buf += SIZEOF(fsQueryXInfoReply);
-    
+ 
+    bufleft = rep->length << 2;
+    bufleft -= SIZEOF(fsQueryXInfoReply);
+
     /* move the data over */
     fsUnpack_XFontInfoHeader(rep, pInfo);
     
@@ -903,19 +907,52 @@ fs_read_query_info(FontPathElementPtr fp
     _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);