configure.ac | 10 ++-------- src/XRecord.c | 54 +++++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 41 insertions(+), 23 deletions(-)
New commits: commit 9f5621a410f18149d4c76b02daa7f1a98b4a2c16 Author: Matthieu Herrb <matthieu.he...@laas.fr> Date: Tue Oct 4 21:28:17 2016 +0200 libXtst 1.2.3 Signed-off-by: Matthieu Herrb <matthieu.he...@laas.fr> diff --git a/configure.ac b/configure.ac index 34ae352..466f431 100644 --- a/configure.ac +++ b/configure.ac @@ -22,7 +22,7 @@ # Initialize Autoconf AC_PREREQ([2.60]) -AC_INIT([libXtst], [1.2.2], +AC_INIT([libXtst], [1.2.3], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [libXtst]) AC_CONFIG_SRCDIR([Makefile.am]) AC_CONFIG_HEADERS([config.h]) commit 9556ad67af3129ec4a7a4f4b54a0d59701beeae3 Author: Tobias Stoeckmann <tob...@stoeckmann.org> Date: Sun Sep 25 21:37:01 2016 +0200 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 <tob...@stoeckmann.org> Reviewed-by: Matthieu Herrb <matth...@herrb.eu> 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) { commit 48d2656fa1dd98e9d88b31211fa4f09f813e7b30 Author: Michael Joost <m...@michael-joost.de> Date: Mon Nov 18 16:11:26 2013 +0100 Remove fallback for _XEatDataWords, require libX11 1.6 for it _XEatDataWords was orignally introduced with the May 2013 security patches, and in order to ease the process of delivering those, fallback versions of _XEatDataWords were included in the X extension library patches so they could be applied to older versions that didn't have libX11 1.6 yet. Now that we're past that hurdle, we can drop the fallbacks and just require libX11 1.6 for building new versions of the extension libraries. Reviewed-by: Alan Coopersmith <alan.coopersm...@oracle.com> Signed-off-by: Alan Coopersmith <alan.coopersm...@oracle.com> diff --git a/configure.ac b/configure.ac index c169598..34ae352 100644 --- a/configure.ac +++ b/configure.ac @@ -45,13 +45,7 @@ XORG_WITH_XSLTPROC XORG_CHECK_SGML_DOCTOOLS(1.8) # Obtain compiler/linker options for depedencies -PKG_CHECK_MODULES(XTST, x11 [xext >= 1.0.99.4] xi [recordproto >= 1.13.99.1] [xextproto >= 7.0.99.3] inputproto) - -# Check for _XEatDataWords function that may be patched into older Xlib release -SAVE_LIBS="$LIBS" -LIBS="$XTST_LIBS" -AC_CHECK_FUNCS([_XEatDataWords]) -LIBS="$SAVE_LIBS" +PKG_CHECK_MODULES(XTST, [x11 >= 1.6] [xext >= 1.0.99.4] xi [recordproto >= 1.13.99.1] [xextproto >= 7.0.99.3] inputproto) # Determine if the source for man pages is available # It may already be present (tarball) or can be generated using xmlto diff --git a/src/XRecord.c b/src/XRecord.c index 5bbd5ac..50420c0 100644 --- a/src/XRecord.c +++ b/src/XRecord.c @@ -61,17 +61,6 @@ from The Open Group. #include <X11/extensions/record.h> #include <limits.h> -#ifndef HAVE__XEATDATAWORDS -static inline void _XEatDataWords(Display *dpy, unsigned long n) -{ -# ifndef LONG64 - if (n >= (ULONG_MAX >> 2)) - _XIOError(dpy); -# endif - _XEatData (dpy, n << 2); -} -#endif - static XExtensionInfo _xrecord_info_data; static XExtensionInfo *xrecord_info = &_xrecord_info_data; static const char *xrecord_extension_name = RECORD_NAME;