Fix CVE-2016-7942: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-7942 Patch copied from upstream source repository: https://cgit.freedesktop.org/xorg/lib/libX11/commit/?id=8ea762f94f4c942d898fdeb590a1630c83235c17 From 8ea762f94f4c942d898fdeb590a1630c83235c17 Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Sun, 25 Sep 2016 21:25:25 +0200 Subject: [PATCH] Validation of server responses in XGetImage() Check if enough bytes were received for specified image type and geometry. Otherwise GetPixel and other functions could trigger an out of boundary read later on. Signed-off-by: Tobias Stoeckmann Reviewed-by: Matthieu Herrb --- src/GetImage.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/GetImage.c b/src/GetImage.c index c461abc..ff32d58 100644 --- a/src/GetImage.c +++ b/src/GetImage.c @@ -59,6 +59,7 @@ XImage *XGetImage ( char *data; unsigned long nbytes; XImage *image; + int planes; LockDisplay(dpy); GetReq (GetImage, req); /* @@ -91,18 +92,28 @@ XImage *XGetImage ( return (XImage *) NULL; } _XReadPad (dpy, data, nbytes); - if (format == XYPixmap) - image = XCreateImage(dpy, _XVIDtoVisual(dpy, rep.visual), - Ones (plane_mask & - (((unsigned long)0xFFFFFFFF) >> (32 - rep.depth))), - format, 0, data, width, height, dpy->bitmap_pad, 0); - else /* format == ZPixmap */ - image = XCreateImage (dpy, _XVIDtoVisual(dpy, rep.visual), - rep.depth, ZPixmap, 0, data, width, height, - _XGetScanlinePad(dpy, (int) rep.depth), 0); + if (format == XYPixmap) { + image = XCreateImage(dpy, _XVIDtoVisual(dpy, rep.visual), + Ones (plane_mask & + (((unsigned long)0xFFFFFFFF) >> (32 - rep.depth))), + format, 0, data, width, height, dpy->bitmap_pad, 0); + planes = image->depth; + } else { /* format == ZPixmap */ + image = XCreateImage (dpy, _XVIDtoVisual(dpy, rep.visual), + rep.depth, ZPixmap, 0, data, width, height, + _XGetScanlinePad(dpy, (int) rep.depth), 0); + planes = 1; + } if (!image) Xfree(data); + if (planes < 1 || image->height < 1 || image->bytes_per_line < 1 || + INT_MAX / image->height <= image->bytes_per_line || + INT_MAX / planes <= image->height * image->bytes_per_line || + nbytes < planes * image->height * image->bytes_per_line) { + XDestroyImage(image); + image = NULL; + } UnlockDisplay(dpy); SyncHandle(); return (image); -- 2.10.1