[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

libx11: Changes to 'debian-wheezy'



 debian/changelog                      |   16 +++++++++
 debian/patches/016_CVE-2013-7439.diff |   60 ++++++++++++++++++++++++++++++++++
 debian/patches/series                 |    1 
 src/FontNames.c                       |   25 ++++++++++----
 src/GetImage.c                        |   29 +++++++++++-----
 src/ListExt.c                         |   12 ++++--
 src/ModMap.c                          |    3 +
 7 files changed, 126 insertions(+), 20 deletions(-)

New commits:
commit 04d11ed0a78465624aa9e94e0354e15902f9c447
Author: Emilio Pozuelo Monfort <pochu@debian.org>
Date:   Thu Oct 27 00:42:50 2016 +0200

    Upload to wheezy-security

diff --git a/debian/changelog b/debian/changelog
index 4c0049e..ae6b0e7 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,13 @@
+libx11 (2:1.5.0-1+deb7u3) wheezy-security; urgency=medium
+
+  * Cherry-pick upstream commits 8c29f16 and 8ea762f:
+    CVE-2016-7942, CVE-2016-7943: validate server responses to
+    prevent out of bounds accesses.
+  * Also cherry-pick upstream commit 20a3f99, which fixes a memory leak
+    in the above patches.
+
+ -- Emilio Pozuelo Monfort <pochu@debian.org>  Thu, 27 Oct 2016 00:42:54 +0200
+
 libx11 (2:1.5.0-1+deb7u2) wheezy-security; urgency=low
 
   * CVE-2013-7439

commit 040102eb4ef321b582f3dbc620acc5437c9e0814
Author: Emilio Pozuelo Monfort <pochu@debian.org>
Date:   Tue Oct 25 21:30:15 2016 +0200

    Plug a memory leak
    
    This was introduced in 8ea762f.
    
    Reported-by: Julien Cristau <jcristau@debian.org>
    Signed-off-by: Emilio Pozuelo Monfort <pochu@debian.org>
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>

diff --git a/src/FontNames.c b/src/FontNames.c
index 55d1aba..86db2e5 100644
--- a/src/FontNames.c
+++ b/src/FontNames.c
@@ -98,12 +98,14 @@ int *actualCount)	/* RETURN */
 		    *ch = '\0';  /* and replace with null-termination */
 		    count++;
 		} else {
+                    Xfree(ch);
                     Xfree(flist);
                     flist = NULL;
                     count = 0;
                     break;
 		}
 	    } else {
+                Xfree(ch);
                 Xfree(flist);
                 flist = NULL;
                 count = 0;

commit 6bfcc1abfa5a353966260a9406fa59ce658f9a56
Author: Tobias Stoeckmann <tobias@stoeckmann.org>
Date:   Sun Sep 25 21:25:25 2016 +0200

    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 <tobias@stoeckmann.org>
    Reviewed-by: Matthieu Herrb <matthieu@herrb.eu>

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);

commit 907d930a8be3a7bf78bb891a268b6170e00e9d5f
Author: Tobias Stoeckmann <tobias@stoeckmann.org>
Date:   Sun Sep 25 21:22:57 2016 +0200

    The validation of server responses avoids out of boundary accesses.
    
    v2: FontNames.c  return a NULL list whenever a single
    length field from the server is incohent.
    
    Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
    Reviewed-by: Matthieu Herrb <matthieu@herrb.eu>

diff --git a/src/FontNames.c b/src/FontNames.c
index b5bc7b4..55d1aba 100644
--- a/src/FontNames.c
+++ b/src/FontNames.c
@@ -66,7 +66,7 @@ int *actualCount)	/* RETURN */
 
     if (rep.nFonts) {
 	flist = Xmalloc (rep.nFonts * sizeof(char *));
-	if (rep.length < (LONG_MAX >> 2)) {
+	if (rep.length > 0 && rep.length < (LONG_MAX >> 2)) {
 	    rlen = rep.length << 2;
 	    ch = Xmalloc(rlen + 1);
 	    /* +1 to leave room for last null-terminator */
@@ -93,11 +93,22 @@ int *actualCount)	/* RETURN */
 	    if (ch + length < chend) {
 		flist[i] = ch + 1;  /* skip over length */
 		ch += length + 1;  /* find next length ... */
-		length = *(unsigned char *)ch;
-		*ch = '\0';  /* and replace with null-termination */
-		count++;
-	    } else
-		flist[i] = NULL;
+		if (ch <= chend) {
+		    length = *(unsigned char *)ch;
+		    *ch = '\0';  /* and replace with null-termination */
+		    count++;
+		} else {
+                    Xfree(flist);
+                    flist = NULL;
+                    count = 0;
+                    break;
+		}
+	    } else {
+                Xfree(flist);
+                flist = NULL;
+                count = 0;
+                break;
+            }
 	}
     }
     *actualCount = count;
diff --git a/src/ListExt.c b/src/ListExt.c
index e925c47..9074315 100644
--- a/src/ListExt.c
+++ b/src/ListExt.c
@@ -55,7 +55,7 @@ char **XListExtensions(
 
 	if (rep.nExtensions) {
 	    list = Xmalloc (rep.nExtensions * sizeof (char *));
-	    if (rep.length < (LONG_MAX >> 2)) {
+	    if (rep.length > 0 && rep.length < (LONG_MAX >> 2)) {
 		rlen = rep.length << 2;
 		ch = Xmalloc (rlen + 1);
                 /* +1 to leave room for last null-terminator */
@@ -80,9 +80,13 @@ char **XListExtensions(
 		if (ch + length < chend) {
 		    list[i] = ch+1;  /* skip over length */
 		    ch += length + 1; /* find next length ... */
-		    length = *ch;
-		    *ch = '\0'; /* and replace with null-termination */
-		    count++;
+		    if (ch <= chend) {
+			length = *ch;
+			*ch = '\0'; /* and replace with null-termination */
+			count++;
+		    } else {
+			list[i] = NULL;
+		    }
 		} else
 		    list[i] = NULL;
 	    }
diff --git a/src/ModMap.c b/src/ModMap.c
index 5c5b426..2b7326b 100644
--- a/src/ModMap.c
+++ b/src/ModMap.c
@@ -42,7 +42,8 @@ XGetModifierMapping(register Display *dpy)
     GetEmptyReq(GetModifierMapping, req);
     (void) _XReply (dpy, (xReply *)&rep, 0, xFalse);
 
-    if (rep.length < (LONG_MAX >> 2)) {
+    if (rep.length < (LONG_MAX >> 2) &&
+	(rep.length >> 1) == rep.numKeyPerModifier) {
 	nbytes = (unsigned long)rep.length << 2;
 	res = Xmalloc(sizeof (XModifierKeymap));
 	if (res)

commit 073173b0b051028c3e8d539309c027731052f087
Author: Emilio Pozuelo Monfort <pochu@debian.org>
Date:   Thu Oct 27 00:49:42 2016 +0200

    Add diff for 2:1.5.0-1+deb7u2

diff --git a/debian/changelog b/debian/changelog
index 5e97c6c..4c0049e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+libx11 (2:1.5.0-1+deb7u2) wheezy-security; urgency=low
+
+  * CVE-2013-7439
+
+ -- Moritz Muehlenhoff <jmm@debian.org>  Sat, 11 Apr 2015 20:47:13 +0000
+
 libx11 (2:1.5.0-1+deb7u1) wheezy-security; urgency=high
 
   * CVE-2013-1981: integer overflows calculating memory needs for replies
diff --git a/debian/patches/016_CVE-2013-7439.diff b/debian/patches/016_CVE-2013-7439.diff
new file mode 100644
index 0000000..8e43f0b
--- /dev/null
+++ b/debian/patches/016_CVE-2013-7439.diff
@@ -0,0 +1,60 @@
+From 39547d600a13713e15429f49768e54c3173c828d Mon Sep 17 00:00:00 2001
+From: Karl Tomlinson <xmail@karlt.net>
+Date: Mon, 18 Feb 2013 01:25:34 +0000
+Subject: MakeBigReq: don't move the last word, already handled by Data32
+
+MakeBigReq inserts a length field after the first 4 bytes of the request
+(after req->length), pushing everything else back by 4 bytes.
+
+The current memmove moves everything but the first 4 bytes back.
+If a request aligns to the end of the buffer pointer when MakeBigReq is
+invoked for that request, this runs over the buffer.
+Instead, we need to memmove minus the first 4 bytes (which aren't moved),
+minus the last 4 bytes (so we still align to the previous tail).
+
+The 4 bytes that fell out are already handled with Data32, which will
+handle the buffermax correctly.
+
+The case where req->length = 1 was already not functional.
+
+Reported by Abhishek Arya <inferno@chromium.org>.
+
+https://bugzilla.mozilla.org/show_bug.cgi?id=803762
+
+Reviewed-by: Jeff Muizelaar <jmuizelaar@mozilla.com>
+Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
+Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+
+[jmm: Backport to 1.5.0]
+
+diff -aur libx11-1.5.0.orig/include/X11/Xlibint.h libx11-1.5.0/include/X11/Xlibint.h
+--- libx11-1.5.0.orig/include/X11/Xlibint.h	2015-04-11 22:42:29.000000000 +0200
++++ libx11-1.5.0/include/X11/Xlibint.h	2015-04-11 22:44:08.171914914 +0200
+@@ -509,7 +509,7 @@
+     unsigned long _BRlen = req->length - 1; \
+     req->length = 0; \
+     memcpy(_BRdat, ((char *)req) + (_BRlen << 2), 4); \
+-    memmove(((char *)req) + 8, ((char *)req) + 4, _BRlen << 2); \
++    memmove(((char *)req) + 8, ((char *)req) + 4, (_BRlen - 1) << 2); \
+     memcpy(((char *)req) + 4, _BRdat, 4); \
+     Data32(dpy, (long *)&_BRdat, 4); \
+     }
+@@ -521,7 +521,7 @@
+     CARD32 _BRlen = req->length - 1; \
+     req->length = 0; \
+     _BRdat = ((CARD32 *)req)[_BRlen]; \
+-    memmove(((char *)req) + 8, ((char *)req) + 4, _BRlen << 2); \
++    memmove(((char *)req) + 8, ((char *)req) + 4, (_BRlen - 1) << 2); \
+     ((CARD32 *)req)[1] = _BRlen + n + 2; \
+     Data32(dpy, &_BRdat, 4); \
+     }
+@@ -532,7 +532,7 @@
+     CARD32 _BRlen = req->length - 1; \
+     req->length = 0; \
+     _BRdat = ((CARD32 *)req)[_BRlen]; \
+-    memmove(((char *)req) + 8, ((char *)req) + 4, _BRlen << 2); \
++    memmove(((char *)req) + 8, ((char *)req) + 4, (_BRlen - 1) << 2); \
+     ((CARD32 *)req)[1] = _BRlen + n + 2; \
+     Data32(dpy, &_BRdat, 4); \
+     }
+
diff --git a/debian/patches/series b/debian/patches/series
index 7b1ae6f..d96cf73 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -6,3 +6,4 @@
 008_remove_ko_Compose.diff
 009_remove_th_Compose.diff
 015_russian_locale_alias.diff
+016_CVE-2013-7439.diff


Reply to: