From mboxrd@z Thu Jan 1 00:00:00 1970 From: Leo Famulari Subject: [PATCH 6/8] gnu: libxtst: Fix CVE-2016-{7951,7952}. Date: Wed, 5 Oct 2016 13:55:59 -0400 Message-ID: <02d6945c5f15085059b42ec1fad4422f62ffc2a7.1475690088.git.leo@famulari.name> References: Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:51916) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1brqQw-0004Uk-GG for guix-devel@gnu.org; Wed, 05 Oct 2016 13:56:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1brqQt-0000zd-MO for guix-devel@gnu.org; Wed, 05 Oct 2016 13:56:45 -0400 Received: from out1-smtp.messagingengine.com ([66.111.4.25]:40705) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1brqQs-0000wL-B0 for guix-devel@gnu.org; Wed, 05 Oct 2016 13:56:43 -0400 Received: from localhost.localdomain (c-73-188-17-148.hsd1.pa.comcast.net [73.188.17.148]) by mail.messagingengine.com (Postfix) with ESMTPA id A3155F2D2D for ; Wed, 5 Oct 2016 13:56:25 -0400 (EDT) In-Reply-To: In-Reply-To: References: List-Id: "Development of GNU Guix and the GNU System distribution." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-devel-bounces+gcggd-guix-devel=m.gmane.org@gnu.org Sender: "Guix-devel" To: guix-devel@gnu.org * gnu/packages/patches/libxtst-CVE-2016-7951-CVE-2016-7952.patch: New file. * gnu/local.mk (dist_patch_DATA): Add it. * gnu/packages/xorg.scm (libxtst)[replacement]: New field. (libxtst/fixed): New variable. --- gnu/local.mk | 1 + .../libxtst-CVE-2016-7951-CVE-2016-7952.patch | 152 +++++++++++++++++++++ gnu/packages/xorg.scm | 8 ++ 3 files changed, 161 insertions(+) create mode 100644 gnu/packages/patches/libxtst-CVE-2016-7951-CVE-2016-7952.patch diff --git a/gnu/local.mk b/gnu/local.mk index ec237d9..7489ab7 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -676,6 +676,7 @@ dist_patch_DATA = \ %D%/packages/patches/libxrandr-CVE-2016-7947-CVE-2016-7948.patch \ %D%/packages/patches/libxrender-CVE-2016-7949.patch \ %D%/packages/patches/libxrender-CVE-2016-7950.patch \ + %D%/packages/patches/libxtst-CVE-2016-7951-CVE-2016-7952.patch \ %D%/packages/patches/libxslt-generated-ids.patch \ %D%/packages/patches/lirc-localstatedir.patch \ %D%/packages/patches/llvm-for-extempore.patch \ diff --git a/gnu/packages/patches/libxtst-CVE-2016-7951-CVE-2016-7952.patch b/gnu/packages/patches/libxtst-CVE-2016-7951-CVE-2016-7952.patch new file mode 100644 index 0000000..9df6cf3 --- /dev/null +++ b/gnu/packages/patches/libxtst-CVE-2016-7951-CVE-2016-7952.patch @@ -0,0 +1,152 @@ +Fix CVE-2016-7951 and CVE-2016-7952 + +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-7951 +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-7952 + +Patch copied from upstream source repository: + +https://cgit.freedesktop.org/xorg/lib/libXtst/commit/?id=9556ad67af3129ec4a7a4f4b54a0d59701beeae3 + +From 9556ad67af3129ec4a7a4f4b54a0d59701beeae3 Mon Sep 17 00:00:00 2001 +From: Tobias Stoeckmann +Date: Sun, 25 Sep 2016 21:37:01 +0200 +Subject: [PATCH] Out of boundary access and endless loop in libXtst + +A lack of range checks in libXtst allows out of boundary accesses. +The checks have to be done in-place here, because it cannot be done +without in-depth knowledge of the read data. + +If XRecordStartOfData, XRecordEndOfData, or XRecordClientDied +without a client sequence have attached data, an endless loop would +occur. The do-while-loop continues until the current index reaches +the end. But in these cases, the current index would not be +incremented, leading to an endless processing. + +Signed-off-by: Tobias Stoeckmann +Reviewed-by: Matthieu Herrb +--- + src/XRecord.c | 43 +++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 39 insertions(+), 4 deletions(-) + +diff --git a/src/XRecord.c b/src/XRecord.c +index 50420c0..fefd842 100644 +--- a/src/XRecord.c ++++ b/src/XRecord.c +@@ -749,15 +749,23 @@ parse_reply_call_callback( + switch (rep->category) { + case XRecordFromServer: + if (rep->elementHeader&XRecordFromServerTime) { ++ if (current_index + 4 > rep->length << 2) ++ return Error; + EXTRACT_CARD32(rep->clientSwapped, + reply->buf+current_index, + data->server_time); + current_index += 4; + } ++ if (current_index + 1 > rep->length << 2) ++ return Error; + switch (reply->buf[current_index]) { + case X_Reply: /* reply */ ++ if (current_index + 8 > rep->length << 2) ++ return Error; + EXTRACT_CARD32(rep->clientSwapped, + reply->buf+current_index+4, datum_bytes); ++ if (datum_bytes < 0 || datum_bytes > ((INT_MAX >> 2) - 8)) ++ return Error; + datum_bytes = (datum_bytes+8) << 2; + break; + default: /* error or event */ +@@ -766,52 +774,73 @@ parse_reply_call_callback( + break; + case XRecordFromClient: + if (rep->elementHeader&XRecordFromClientTime) { ++ if (current_index + 4 > rep->length << 2) ++ return Error; + EXTRACT_CARD32(rep->clientSwapped, + reply->buf+current_index, + data->server_time); + current_index += 4; + } + if (rep->elementHeader&XRecordFromClientSequence) { ++ if (current_index + 4 > rep->length << 2) ++ return Error; + EXTRACT_CARD32(rep->clientSwapped, + reply->buf+current_index, + data->client_seq); + current_index += 4; + } ++ if (current_index + 4 > rep->length<<2) ++ return Error; + if (reply->buf[current_index+2] == 0 + && reply->buf[current_index+3] == 0) /* needn't swap 0 */ + { /* BIG-REQUESTS */ ++ if (current_index + 8 > rep->length << 2) ++ return Error; + EXTRACT_CARD32(rep->clientSwapped, + reply->buf+current_index+4, datum_bytes); + } else { + EXTRACT_CARD16(rep->clientSwapped, + reply->buf+current_index+2, datum_bytes); + } ++ if (datum_bytes < 0 || datum_bytes > INT_MAX >> 2) ++ return Error; + datum_bytes <<= 2; + break; + case XRecordClientStarted: ++ if (current_index + 8 > rep->length << 2) ++ return Error; + EXTRACT_CARD16(rep->clientSwapped, + reply->buf+current_index+6, datum_bytes); + datum_bytes = (datum_bytes+2) << 2; + break; + case XRecordClientDied: + if (rep->elementHeader&XRecordFromClientSequence) { ++ if (current_index + 4 > rep->length << 2) ++ return Error; + EXTRACT_CARD32(rep->clientSwapped, + reply->buf+current_index, + data->client_seq); + current_index += 4; +- } +- /* fall through */ ++ } else if (current_index < rep->length << 2) ++ return Error; ++ datum_bytes = 0; ++ break; + case XRecordStartOfData: + case XRecordEndOfData: ++ if (current_index < rep->length << 2) ++ return Error; + datum_bytes = 0; ++ break; + } + + if (datum_bytes > 0) { +- if (current_index + datum_bytes > rep->length << 2) ++ if (INT_MAX - datum_bytes < (rep->length << 2) - current_index) { + fprintf(stderr, + "XRecord: %lu-byte reply claims %d-byte element (seq %lu)\n", +- (long)rep->length << 2, current_index + datum_bytes, ++ (unsigned long)rep->length << 2, current_index + datum_bytes, + dpy->last_request_read); ++ return Error; ++ } + /* + * This assignment (and indeed the whole buffer sharing + * scheme) assumes arbitrary 4-byte boundaries are +@@ -863,6 +892,12 @@ XRecordEnableContext(Display *dpy, XRecordContext context, + return 0; + } + ++ if (rep.length > INT_MAX >> 2) { ++ UnlockDisplay(dpy); ++ SyncHandle(); ++ return 0; ++ } ++ + if (rep.length > 0) { + reply = alloc_reply_buffer(info, rep.length<<2); + if (!reply) { +-- +2.10.1 + diff --git a/gnu/packages/xorg.scm b/gnu/packages/xorg.scm index 2df6631..111de2b 100644 --- a/gnu/packages/xorg.scm +++ b/gnu/packages/xorg.scm @@ -4639,6 +4639,7 @@ cannot be adequately worked around on the client side of the wire.") (define-public libxtst (package (name "libxtst") + (replacement libxtst/fixed) (version "1.2.2") (source (origin @@ -4674,6 +4675,13 @@ The RECORD extension supports the recording and reporting of all core X protocol and arbitrary X extension protocol.") (license license:x11))) +(define libxtst/fixed + (package + (inherit libxtst) + (source (origin + (inherit (package-source libxtst)) + (patches (search-patches + "libxtst-CVE-2016-7951-CVE-2016-7952.patch")))))) (define-public libxv (package -- 2.10.1