Bump libXi to 1.7.8
[unleashed-userland.git] / components / x11 / libXrandr / patches / 01-CVE-2016-7947+CVE-2016-7948.patch
blob608db91fbb4a11915ef356aa94f7b3a49f9d1736
1 From a0df3e1c7728205e5c7650b2e6dce684139254a6 Mon Sep 17 00:00:00 2001
2 From: Tobias Stoeckmann <tobias@stoeckmann.org>
3 Date: Sun, 25 Sep 2016 22:21:40 +0200
4 Subject: Avoid out of boundary accesses on illegal responses
6 The responses of the connected X server have to be properly checked
7 to avoid out of boundary accesses that could otherwise be triggered
8 by a malicious server.
10 Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
11 Reviewed-by: Matthieu Herrb <matthieu@herrb.eu>
13 diff --git a/src/XrrConfig.c b/src/XrrConfig.c
14 index 2f0282b..e68c45a 100644
15 --- a/src/XrrConfig.c
16 +++ b/src/XrrConfig.c
17 @@ -29,6 +29,7 @@
18 #include <config.h>
19 #endif
21 +#include <limits.h>
22 #include <stdio.h>
23 #include <X11/Xlib.h>
24 /* we need to be able to manipulate the Display structure on events */
25 @@ -272,23 +273,30 @@ static XRRScreenConfiguration *_XRRGetScreenInfo (Display *dpy,
26 rep.rate = 0;
27 rep.nrateEnts = 0;
29 + if (rep.length < INT_MAX >> 2) {
30 + nbytes = (long) rep.length << 2;
32 - nbytes = (long) rep.length << 2;
33 + nbytesRead = (long) (rep.nSizes * SIZEOF (xScreenSizes) +
34 + ((rep.nrateEnts + 1)& ~1) * 2 /* SIZEOF(CARD16) */);
36 - nbytesRead = (long) (rep.nSizes * SIZEOF (xScreenSizes) +
37 - ((rep.nrateEnts + 1)& ~1) * 2 /* SIZEOF (CARD16) */);
38 + /*
39 + * first we must compute how much space to allocate for
40 + * randr library's use; we'll allocate the structures in a single
41 + * allocation, on cleanlyness grounds.
42 + */
44 - /*
45 - * first we must compute how much space to allocate for
46 - * randr library's use; we'll allocate the structures in a single
47 - * allocation, on cleanlyness grounds.
48 - */
49 + rbytes = sizeof (XRRScreenConfiguration) +
50 + (rep.nSizes * sizeof (XRRScreenSize) +
51 + rep.nrateEnts * sizeof (int));
53 - rbytes = sizeof (XRRScreenConfiguration) +
54 - (rep.nSizes * sizeof (XRRScreenSize) +
55 - rep.nrateEnts * sizeof (int));
56 + scp = (struct _XRRScreenConfiguration *) Xmalloc(rbytes);
57 + } else {
58 + nbytes = 0;
59 + nbytesRead = 0;
60 + rbytes = 0;
61 + scp = NULL;
62 + }
64 - scp = (struct _XRRScreenConfiguration *) Xmalloc(rbytes);
65 if (scp == NULL) {
66 _XEatData (dpy, (unsigned long) nbytes);
67 return NULL;
68 diff --git a/src/XrrCrtc.c b/src/XrrCrtc.c
69 index 5ae35c5..6665092 100644
70 --- a/src/XrrCrtc.c
71 +++ b/src/XrrCrtc.c
72 @@ -24,6 +24,7 @@
73 #include <config.h>
74 #endif
76 +#include <limits.h>
77 #include <stdio.h>
78 #include <X11/Xlib.h>
79 /* we need to be able to manipulate the Display structure on events */
80 @@ -57,22 +58,33 @@ XRRGetCrtcInfo (Display *dpy, XRRScreenResources *resources, RRCrtc crtc)
81 return NULL;
84 - nbytes = (long) rep.length << 2;
85 + if (rep.length < INT_MAX >> 2)
86 + {
87 + nbytes = (long) rep.length << 2;
89 - nbytesRead = (long) (rep.nOutput * 4 +
90 - rep.nPossibleOutput * 4);
91 + nbytesRead = (long) (rep.nOutput * 4 +
92 + rep.nPossibleOutput * 4);
94 - /*
95 - * first we must compute how much space to allocate for
96 - * randr library's use; we'll allocate the structures in a single
97 - * allocation, on cleanlyness grounds.
98 - */
99 + /*
100 + * first we must compute how much space to allocate for
101 + * randr library's use; we'll allocate the structures in a single
102 + * allocation, on cleanlyness grounds.
103 + */
105 - rbytes = (sizeof (XRRCrtcInfo) +
106 - rep.nOutput * sizeof (RROutput) +
107 - rep.nPossibleOutput * sizeof (RROutput));
108 + rbytes = (sizeof (XRRCrtcInfo) +
109 + rep.nOutput * sizeof (RROutput) +
110 + rep.nPossibleOutput * sizeof (RROutput));
112 + xci = (XRRCrtcInfo *) Xmalloc(rbytes);
114 + else
116 + nbytes = 0;
117 + nbytesRead = 0;
118 + rbytes = 0;
119 + xci = NULL;
122 - xci = (XRRCrtcInfo *) Xmalloc(rbytes);
123 if (xci == NULL) {
124 _XEatDataWords (dpy, rep.length);
125 UnlockDisplay (dpy);
126 @@ -194,12 +206,21 @@ XRRGetCrtcGamma (Display *dpy, RRCrtc crtc)
127 if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
128 goto out;
130 - nbytes = (long) rep.length << 2;
131 + if (rep.length < INT_MAX >> 2)
133 + nbytes = (long) rep.length << 2;
135 - /* three channels of CARD16 data */
136 - nbytesRead = (rep.size * 2 * 3);
137 + /* three channels of CARD16 data */
138 + nbytesRead = (rep.size * 2 * 3);
140 - crtc_gamma = XRRAllocGamma (rep.size);
141 + crtc_gamma = XRRAllocGamma (rep.size);
143 + else
145 + nbytes = 0;
146 + nbytesRead = 0;
147 + crtc_gamma = NULL;
150 if (!crtc_gamma)
152 @@ -357,7 +378,7 @@ XRRGetCrtcTransform (Display *dpy,
153 xRRGetCrtcTransformReq *req;
154 int major_version, minor_version;
155 XRRCrtcTransformAttributes *attr;
156 - char *extra = NULL, *e;
157 + char *extra = NULL, *end = NULL, *e;
158 int p;
160 *attributes = NULL;
161 @@ -395,9 +416,17 @@ XRRGetCrtcTransform (Display *dpy,
162 else
164 int extraBytes = rep.length * 4 - CrtcTransformExtra;
165 - extra = Xmalloc (extraBytes);
166 + if (rep.length < INT_MAX / 4 &&
167 + rep.length * 4 >= CrtcTransformExtra) {
168 + extra = Xmalloc (extraBytes);
169 + end = extra + extraBytes;
170 + } else
171 + extra = NULL;
172 if (!extra) {
173 - _XEatDataWords (dpy, rep.length - (CrtcTransformExtra >> 2));
174 + if (rep.length > (CrtcTransformExtra >> 2))
175 + _XEatDataWords (dpy, rep.length - (CrtcTransformExtra >> 2));
176 + else
177 + _XEatDataWords (dpy, rep.length);
178 UnlockDisplay (dpy);
179 SyncHandle ();
180 return False;
181 @@ -429,22 +458,38 @@ XRRGetCrtcTransform (Display *dpy,
183 e = extra;
185 + if (e + rep.pendingNbytesFilter > end) {
186 + XFree (extra);
187 + return False;
189 memcpy (attr->pendingFilter, e, rep.pendingNbytesFilter);
190 attr->pendingFilter[rep.pendingNbytesFilter] = '\0';
191 e += (rep.pendingNbytesFilter + 3) & ~3;
192 for (p = 0; p < rep.pendingNparamsFilter; p++) {
193 INT32 f;
194 + if (e + 4 > end) {
195 + XFree (extra);
196 + return False;
198 memcpy (&f, e, 4);
199 e += 4;
200 attr->pendingParams[p] = (XFixed) f;
202 attr->pendingNparams = rep.pendingNparamsFilter;
204 + if (e + rep.currentNbytesFilter > end) {
205 + XFree (extra);
206 + return False;
208 memcpy (attr->currentFilter, e, rep.currentNbytesFilter);
209 attr->currentFilter[rep.currentNbytesFilter] = '\0';
210 e += (rep.currentNbytesFilter + 3) & ~3;
211 for (p = 0; p < rep.currentNparamsFilter; p++) {
212 INT32 f;
213 + if (e + 4 > end) {
214 + XFree (extra);
215 + return False;
217 memcpy (&f, e, 4);
218 e += 4;
219 attr->currentParams[p] = (XFixed) f;
220 diff --git a/src/XrrMonitor.c b/src/XrrMonitor.c
221 index a9eaa7b..adc5330 100644
222 --- a/src/XrrMonitor.c
223 +++ b/src/XrrMonitor.c
224 @@ -24,6 +24,7 @@
225 #include <config.h>
226 #endif
228 +#include <limits.h>
229 #include <stdio.h>
230 #include <X11/Xlib.h>
231 /* we need to be able to manipulate the Display structure on events */
232 @@ -65,6 +66,15 @@ XRRGetMonitors(Display *dpy, Window window, Bool get_active, int *nmonitors)
233 return NULL;
236 + if (rep.length > INT_MAX >> 2 ||
237 + rep.nmonitors > INT_MAX / SIZEOF(xRRMonitorInfo) ||
238 + rep.noutputs > INT_MAX / 4 ||
239 + rep.nmonitors * SIZEOF(xRRMonitorInfo) > INT_MAX - rep.noutputs * 4) {
240 + _XEatData (dpy, rep.length);
241 + UnlockDisplay (dpy);
242 + SyncHandle ();
243 + return NULL;
245 nbytes = (long) rep.length << 2;
246 nmon = rep.nmonitors;
247 noutput = rep.noutputs;
248 @@ -111,6 +121,14 @@ XRRGetMonitors(Display *dpy, Window window, Bool get_active, int *nmonitors)
249 mon[m].outputs = output;
250 buf += SIZEOF (xRRMonitorInfo);
251 xoutput = (CARD32 *) buf;
252 + if (xmon->noutput > rep.noutputs) {
253 + Xfree(buf);
254 + Xfree(mon);
255 + UnlockDisplay (dpy);
256 + SyncHandle ();
257 + return NULL;
259 + rep.noutputs -= xmon->noutput;
260 for (o = 0; o < xmon->noutput; o++)
261 output[o] = xoutput[o];
262 output += xmon->noutput;
263 diff --git a/src/XrrOutput.c b/src/XrrOutput.c
264 index 85f0b6e..30f3d40 100644
265 --- a/src/XrrOutput.c
266 +++ b/src/XrrOutput.c
267 @@ -25,6 +25,7 @@
268 #include <config.h>
269 #endif
271 +#include <limits.h>
272 #include <stdio.h>
273 #include <X11/Xlib.h>
274 /* we need to be able to manipulate the Display structure on events */
275 @@ -60,6 +61,16 @@ XRRGetOutputInfo (Display *dpy, XRRScreenResources *resources, RROutput output)
276 return NULL;
279 + if (rep.length > INT_MAX >> 2 || rep.length < (OutputInfoExtra >> 2))
281 + if (rep.length > (OutputInfoExtra >> 2))
282 + _XEatDataWords (dpy, rep.length - (OutputInfoExtra >> 2));
283 + else
284 + _XEatDataWords (dpy, rep.length);
285 + UnlockDisplay (dpy);
286 + SyncHandle ();
287 + return NULL;
289 nbytes = ((long) (rep.length) << 2) - OutputInfoExtra;
291 nbytesRead = (long) (rep.nCrtcs * 4 +
292 diff --git a/src/XrrProvider.c b/src/XrrProvider.c
293 index 9e620c7..d796cd0 100644
294 --- a/src/XrrProvider.c
295 +++ b/src/XrrProvider.c
296 @@ -25,6 +25,7 @@
297 #include <config.h>
298 #endif
300 +#include <limits.h>
301 #include <stdio.h>
302 #include <X11/Xlib.h>
303 /* we need to be able to manipulate the Display structure on events */
304 @@ -59,12 +60,20 @@ XRRGetProviderResources(Display *dpy, Window window)
305 return NULL;
308 - nbytes = (long) rep.length << 2;
309 + if (rep.length < INT_MAX >> 2) {
310 + nbytes = (long) rep.length << 2;
312 - nbytesRead = (long) (rep.nProviders * 4);
313 + nbytesRead = (long) (rep.nProviders * 4);
315 - rbytes = (sizeof(XRRProviderResources) + rep.nProviders * sizeof(RRProvider));
316 - xrpr = (XRRProviderResources *) Xmalloc(rbytes);
317 + rbytes = (sizeof(XRRProviderResources) + rep.nProviders *
318 + sizeof(RRProvider));
319 + xrpr = (XRRProviderResources *) Xmalloc(rbytes);
320 + } else {
321 + nbytes = 0;
322 + nbytesRead = 0;
323 + rbytes = 0;
324 + xrpr = NULL;
327 if (xrpr == NULL) {
328 _XEatDataWords (dpy, rep.length);
329 @@ -121,6 +130,17 @@ XRRGetProviderInfo(Display *dpy, XRRScreenResources *resources, RRProvider provi
330 return NULL;
333 + if (rep.length > INT_MAX >> 2 || rep.length < ProviderInfoExtra >> 2)
335 + if (rep.length < ProviderInfoExtra >> 2)
336 + _XEatDataWords (dpy, rep.length);
337 + else
338 + _XEatDataWords (dpy, rep.length - (ProviderInfoExtra >> 2));
339 + UnlockDisplay (dpy);
340 + SyncHandle ();
341 + return NULL;
344 nbytes = ((long) rep.length << 2) - ProviderInfoExtra;
346 nbytesRead = (long)(rep.nCrtcs * 4 +
347 diff --git a/src/XrrScreen.c b/src/XrrScreen.c
348 index b8ce7e5..1f7ffe6 100644
349 --- a/src/XrrScreen.c
350 +++ b/src/XrrScreen.c
351 @@ -24,6 +24,7 @@
352 #include <config.h>
353 #endif
355 +#include <limits.h>
356 #include <stdio.h>
357 #include <X11/Xlib.h>
358 /* we need to be able to manipulate the Display structure on events */
359 @@ -105,27 +106,36 @@ doGetScreenResources (Display *dpy, Window window, int poll)
360 xrri->has_rates = _XRRHasRates (xrri->minor_version, xrri->major_version);
363 - nbytes = (long) rep.length << 2;
364 + if (rep.length < INT_MAX >> 2) {
365 + nbytes = (long) rep.length << 2;
367 - nbytesRead = (long) (rep.nCrtcs * 4 +
368 - rep.nOutputs * 4 +
369 - rep.nModes * SIZEOF (xRRModeInfo) +
370 - ((rep.nbytesNames + 3) & ~3));
371 + nbytesRead = (long) (rep.nCrtcs * 4 +
372 + rep.nOutputs * 4 +
373 + rep.nModes * SIZEOF (xRRModeInfo) +
374 + ((rep.nbytesNames + 3) & ~3));
376 - /*
377 - * first we must compute how much space to allocate for
378 - * randr library's use; we'll allocate the structures in a single
379 - * allocation, on cleanlyness grounds.
380 - */
381 + /*
382 + * first we must compute how much space to allocate for
383 + * randr library's use; we'll allocate the structures in a single
384 + * allocation, on cleanlyness grounds.
385 + */
387 + rbytes = (sizeof (XRRScreenResources) +
388 + rep.nCrtcs * sizeof (RRCrtc) +
389 + rep.nOutputs * sizeof (RROutput) +
390 + rep.nModes * sizeof (XRRModeInfo) +
391 + rep.nbytesNames + rep.nModes); /* '\0' terminate names */
393 - rbytes = (sizeof (XRRScreenResources) +
394 - rep.nCrtcs * sizeof (RRCrtc) +
395 - rep.nOutputs * sizeof (RROutput) +
396 - rep.nModes * sizeof (XRRModeInfo) +
397 - rep.nbytesNames + rep.nModes); /* '\0' terminate names */
398 + xrsr = (XRRScreenResources *) Xmalloc(rbytes);
399 + wire_names = (char *) Xmalloc (rep.nbytesNames);
400 + } else {
401 + nbytes = 0;
402 + nbytesRead = 0;
403 + rbytes = 0;
404 + xrsr = NULL;
405 + wire_names = NULL;
408 - xrsr = (XRRScreenResources *) Xmalloc(rbytes);
409 - wire_names = (char *) Xmalloc (rep.nbytesNames);
410 if (xrsr == NULL || wire_names == NULL) {
411 Xfree (xrsr);
412 Xfree (wire_names);
413 @@ -174,6 +184,14 @@ doGetScreenResources (Display *dpy, Window window, int poll)
414 wire_name = wire_names;
415 for (i = 0; i < rep.nModes; i++) {
416 xrsr->modes[i].name = names;
417 + if (xrsr->modes[i].nameLength > rep.nbytesNames) {
418 + Xfree (xrsr);
419 + Xfree (wire_names);
420 + UnlockDisplay (dpy);
421 + SyncHandle ();
422 + return NULL;
424 + rep.nbytesNames -= xrsr->modes[i].nameLength;
425 memcpy (names, wire_name, xrsr->modes[i].nameLength);
426 names[xrsr->modes[i].nameLength] = '\0';
427 names += xrsr->modes[i].nameLength + 1;
429 cgit v0.10.2