open-src/lib/libXi/CVE-2013-19XX.patch
changeset 1345 d5dacbb8de2b
equal deleted inserted replaced
1344:800e8c2d47f1 1345:d5dacbb8de2b
       
     1 From bb82c72a1d69eaf60b7586570faf797df967f661 Mon Sep 17 00:00:00 2001
       
     2 From: Alan Coopersmith <[email protected]>
       
     3 Date: Mon, 29 Apr 2013 18:39:34 -0700
       
     4 Subject: [PATCH:libXi] Expand comment on the memory vs. reply ordering in
       
     5  XIGetSelectedEvents()
       
     6 
       
     7 Unpacking from the wire involves un-interleaving the structs & masks,
       
     8 which wasn't obvious to me the first time I read it, so make notes
       
     9 before I forget again.
       
    10 
       
    11 Signed-off-by: Alan Coopersmith <[email protected]>
       
    12 Signed-off-by: Peter Hutterer <[email protected]>
       
    13 ---
       
    14  src/XISelEv.c |   10 ++++++++--
       
    15  1 file changed, 8 insertions(+), 2 deletions(-)
       
    16 
       
    17 diff --git a/src/XISelEv.c b/src/XISelEv.c
       
    18 index fa7eb54..f871222 100644
       
    19 --- a/src/XISelEv.c
       
    20 +++ b/src/XISelEv.c
       
    21 @@ -135,8 +135,14 @@ XIGetSelectedEvents(Display* dpy, Window win, int *num_masks_return)
       
    22  
       
    23      _XRead(dpy, (char*)mask_in, reply.length * 4);
       
    24  
       
    25 -    /* Memory layout of the XIEventMask for a 3 mask reply:
       
    26 -     * [struct a][struct b][struct c][masks a][masks b][masks c]
       
    27 +    /*
       
    28 +     * This function takes interleaved xXIEventMask structs & masks off
       
    29 +     * the wire, such as this 3 mask reply:
       
    30 +     *   [struct a][masks a][struct b][masks b][struct c][masks c]
       
    31 +     * And generates a memory buffer to be returned to callers in which
       
    32 +     * they are not interleaved, so that callers can treat the returned
       
    33 +     * pointer as a simple array of XIEventMask structs, such as:
       
    34 +     *   [struct a][struct b][struct c][masks a][masks b][masks c]
       
    35       */
       
    36      len = reply.num_masks * sizeof(XIEventMask);
       
    37  
       
    38 -- 
       
    39 1.7.9.2
       
    40 
       
    41 From 63841a81a340f1979cf5b0ffa1f7047dca988994 Mon Sep 17 00:00:00 2001
       
    42 From: Alan Coopersmith <[email protected]>
       
    43 Date: Wed, 1 May 2013 23:58:39 -0700
       
    44 Subject: [PATCH:libXi 01/13] Use _XEatDataWords to avoid overflow of
       
    45  rep.length bit shifting
       
    46 
       
    47 rep.length is a CARD32, so rep.length << 2 could overflow in 32-bit builds
       
    48 
       
    49 Signed-off-by: Alan Coopersmith <[email protected]>
       
    50 Reviewed-by: Peter Hutterer <[email protected]>
       
    51 ---
       
    52  configure.ac       |    6 ++++++
       
    53  src/XGMotion.c     |    2 +-
       
    54  src/XGetDCtl.c     |    2 +-
       
    55  src/XGetDProp.c    |    5 ++---
       
    56  src/XGetFCtl.c     |    2 +-
       
    57  src/XGetKMap.c     |    2 +-
       
    58  src/XGetMMap.c     |    2 +-
       
    59  src/XGetProp.c     |    4 +---
       
    60  src/XGtSelect.c    |    2 +-
       
    61  src/XIProperties.c |    7 +++----
       
    62  src/XIint.h        |   14 ++++++++++++++
       
    63  src/XListDProp.c   |    2 +-
       
    64  src/XListDev.c     |    2 +-
       
    65  src/XOpenDev.c     |    2 +-
       
    66  src/XQueryDv.c     |    2 +-
       
    67  15 files changed, 36 insertions(+), 20 deletions(-)
       
    68 
       
    69 diff --git a/configure.ac b/configure.ac
       
    70 index 8dbca38..f5ef1e2 100644
       
    71 --- a/configure.ac
       
    72 +++ b/configure.ac
       
    73 @@ -31,6 +31,12 @@ PKG_CHECK_MODULES(XI, [xproto >= 7.0.13] [x11 >= 1.4.99.1] [xextproto >= 7.0.3]
       
    74  # CFLAGS only for PointerBarrier typedef
       
    75  PKG_CHECK_MODULES(XFIXES, [xfixes >= 5])
       
    76  
       
    77 +# Check for _XEatDataWords function that may be patched into older Xlib releases
       
    78 +SAVE_LIBS="$LIBS"
       
    79 +LIBS="$XI_LIBS"
       
    80 +AC_CHECK_FUNCS([_XEatDataWords])
       
    81 +LIBS="$SAVE_LIBS"
       
    82 +
       
    83  # Check for xmlto and asciidoc for man page conversion
       
    84  # (only needed by people building tarballs)
       
    85  if test "$have_xmlto" = yes && test "$have_asciidoc" = yes; then
       
    86 diff --git a/src/XGMotion.c b/src/XGMotion.c
       
    87 index 99b1c44..5feac85 100644
       
    88 --- a/src/XGMotion.c
       
    89 +++ b/src/XGMotion.c
       
    90 @@ -112,7 +112,7 @@ XGetDeviceMotionEvents(
       
    91  	Xfree(bufp);
       
    92  	Xfree(savp);
       
    93  	*nEvents = 0;
       
    94 -	_XEatData(dpy, (unsigned long)size);
       
    95 +	_XEatDataWords(dpy, rep.length);
       
    96  	UnlockDisplay(dpy);
       
    97  	SyncHandle();
       
    98  	return (NULL);
       
    99 diff --git a/src/XGetDCtl.c b/src/XGetDCtl.c
       
   100 index c66212d..f73a4e8 100644
       
   101 --- a/src/XGetDCtl.c
       
   102 +++ b/src/XGetDCtl.c
       
   103 @@ -95,7 +95,7 @@ XGetDeviceControl(
       
   104  	nbytes = (long)rep.length << 2;
       
   105  	d = (xDeviceState *) Xmalloc((unsigned)nbytes);
       
   106  	if (!d) {
       
   107 -	    _XEatData(dpy, (unsigned long)nbytes);
       
   108 +	    _XEatDataWords(dpy, rep.length);
       
   109  	    goto out;
       
   110  	}
       
   111  	sav = d;
       
   112 diff --git a/src/XGetDProp.c b/src/XGetDProp.c
       
   113 index 5d44f91..f9e8f0c 100644
       
   114 --- a/src/XGetDProp.c
       
   115 +++ b/src/XGetDProp.c
       
   116 @@ -112,14 +112,13 @@ XGetDeviceProperty(Display* dpy, XDevice* dev,
       
   117  	     * This part of the code should never be reached.  If it is,
       
   118  	     * the server sent back a property with an invalid format.
       
   119  	     */
       
   120 -	    nbytes = rep.length << 2;
       
   121 -	    _XEatData(dpy, (unsigned long) nbytes);
       
   122 +	    _XEatDataWords(dpy, rep.length);
       
   123  	    UnlockDisplay(dpy);
       
   124  	    SyncHandle();
       
   125  	    return(BadImplementation);
       
   126  	}
       
   127  	if (! *prop) {
       
   128 -	    _XEatData(dpy, (unsigned long) nbytes);
       
   129 +	    _XEatDataWords(dpy, rep.length);
       
   130  	    UnlockDisplay(dpy);
       
   131  	    SyncHandle();
       
   132  	    return(BadAlloc);
       
   133 diff --git a/src/XGetFCtl.c b/src/XGetFCtl.c
       
   134 index 43afa00..28fab4d 100644
       
   135 --- a/src/XGetFCtl.c
       
   136 +++ b/src/XGetFCtl.c
       
   137 @@ -95,7 +95,7 @@ XGetFeedbackControl(
       
   138  	nbytes = (long)rep.length << 2;
       
   139  	f = (xFeedbackState *) Xmalloc((unsigned)nbytes);
       
   140  	if (!f) {
       
   141 -	    _XEatData(dpy, (unsigned long)nbytes);
       
   142 +	    _XEatDataWords(dpy, rep.length);
       
   143  	    goto out;
       
   144  	}
       
   145  	sav = f;
       
   146 diff --git a/src/XGetKMap.c b/src/XGetKMap.c
       
   147 index 9431fbb..00dde06 100644
       
   148 --- a/src/XGetKMap.c
       
   149 +++ b/src/XGetKMap.c
       
   150 @@ -99,7 +99,7 @@ XGetDeviceKeyMapping(register Display * dpy, XDevice * dev,
       
   151  	if (mapping)
       
   152  	    _XRead(dpy, (char *)mapping, nbytes);
       
   153  	else
       
   154 -	    _XEatData(dpy, (unsigned long)nbytes);
       
   155 +	    _XEatDataWords(dpy, rep.length);
       
   156      }
       
   157  
       
   158      UnlockDisplay(dpy);
       
   159 diff --git a/src/XGetMMap.c b/src/XGetMMap.c
       
   160 index 8a1cdb2..ce10c2d 100644
       
   161 --- a/src/XGetMMap.c
       
   162 +++ b/src/XGetMMap.c
       
   163 @@ -92,7 +92,7 @@ XGetDeviceModifierMapping(
       
   164  	if (res->modifiermap)
       
   165  	    _XReadPad(dpy, (char *)res->modifiermap, nbytes);
       
   166  	else
       
   167 -	    _XEatData(dpy, (unsigned long)nbytes);
       
   168 +	    _XEatDataWords(dpy, rep.length);
       
   169  	res->max_keypermod = rep.numKeyPerModifier;
       
   170      }
       
   171  
       
   172 diff --git a/src/XGetProp.c b/src/XGetProp.c
       
   173 index c5d088b..34bc581 100644
       
   174 --- a/src/XGetProp.c
       
   175 +++ b/src/XGetProp.c
       
   176 @@ -68,7 +68,6 @@ XGetDeviceDontPropagateList(
       
   177      int			*count)
       
   178  {
       
   179      XEventClass *list = NULL;
       
   180 -    int rlen;
       
   181      xGetDeviceDontPropagateListReq *req;
       
   182      xGetDeviceDontPropagateListReply rep;
       
   183      XExtDisplayInfo *info = XInput_find_display(dpy);
       
   184 @@ -90,7 +89,6 @@ XGetDeviceDontPropagateList(
       
   185      *count = rep.count;
       
   186  
       
   187      if (*count) {
       
   188 -	rlen = rep.length << 2;
       
   189  	list = (XEventClass *) Xmalloc(rep.length * sizeof(XEventClass));
       
   190  	if (list) {
       
   191  	    int i;
       
   192 @@ -105,7 +103,7 @@ XGetDeviceDontPropagateList(
       
   193  		list[i] = (XEventClass) ec;
       
   194  	    }
       
   195  	} else
       
   196 -	    _XEatData(dpy, (unsigned long)rlen);
       
   197 +	    _XEatDataWords(dpy, rep.length);
       
   198      }
       
   199  
       
   200      UnlockDisplay(dpy);
       
   201 diff --git a/src/XGtSelect.c b/src/XGtSelect.c
       
   202 index f890db7..5c0f812 100644
       
   203 --- a/src/XGtSelect.c
       
   204 +++ b/src/XGtSelect.c
       
   205 @@ -104,7 +104,7 @@ XGetSelectedExtensionEvents(
       
   206  		(XEventClass *) Xmalloc(*this_client_count *
       
   207  					sizeof(XEventClass));
       
   208  	    if (!*this_client_list) {
       
   209 -		_XEatData(dpy, (unsigned long)tlen + alen);
       
   210 +		_XEatDataWords(dpy, rep.length);
       
   211                  UnlockDisplay(dpy);
       
   212                  SyncHandle();
       
   213  		return (Success);
       
   214 diff --git a/src/XIProperties.c b/src/XIProperties.c
       
   215 index 83a7a68..5e58fb6 100644
       
   216 --- a/src/XIProperties.c
       
   217 +++ b/src/XIProperties.c
       
   218 @@ -64,7 +64,7 @@ XIListProperties(Display* dpy, int deviceid, int *num_props_return)
       
   219          props = (Atom*)Xmalloc(rep.num_properties * sizeof(Atom));
       
   220          if (!props)
       
   221          {
       
   222 -            _XEatData(dpy, rep.num_properties << 2);
       
   223 +            _XEatDataWords(dpy, rep.length);
       
   224              goto cleanup;
       
   225          }
       
   226  
       
   227 @@ -203,8 +203,7 @@ XIGetProperty(Display* dpy, int deviceid, Atom property, long offset,
       
   228  	     * This part of the code should never be reached.  If it is,
       
   229  	     * the server sent back a property with an invalid format.
       
   230  	     */
       
   231 -	    nbytes = rep.length << 2;
       
   232 -	    _XEatData(dpy, nbytes);
       
   233 +	    _XEatDataWords(dpy, rep.length);
       
   234  	    UnlockDisplay(dpy);
       
   235  	    SyncHandle();
       
   236  	    return(BadImplementation);
       
   237 @@ -222,7 +221,7 @@ XIGetProperty(Display* dpy, int deviceid, Atom property, long offset,
       
   238          *data = Xmalloc(rbytes);
       
   239  
       
   240  	if (!(*data)) {
       
   241 -	    _XEatData(dpy, nbytes);
       
   242 +	    _XEatDataWords(dpy, rep.length);
       
   243  	    UnlockDisplay(dpy);
       
   244  	    SyncHandle();
       
   245  	    return(BadAlloc);
       
   246 diff --git a/src/XIint.h b/src/XIint.h
       
   247 index 571bb23..3ddc3c5 100644
       
   248 --- a/src/XIint.h
       
   249 +++ b/src/XIint.h
       
   250 @@ -83,4 +83,18 @@ next_block(void **ptr, int size) {
       
   251      return ret;
       
   252  }
       
   253  
       
   254 +#ifndef HAVE__XEATDATAWORDS
       
   255 +#include <X11/Xmd.h>  /* for LONG64 on 64-bit platforms */
       
   256 +#include <limits.h>
       
   257 +
       
   258 +static inline void _XEatDataWords(Display *dpy, unsigned long n)
       
   259 +{
       
   260 +# ifndef LONG64
       
   261 +    if (n >= (ULONG_MAX >> 2))
       
   262 +        _XIOError(dpy);
       
   263 +# endif
       
   264 +    _XEatData (dpy, n << 2);
       
   265 +}
       
   266 +#endif
       
   267 +
       
   268  #endif
       
   269 diff --git a/src/XListDProp.c b/src/XListDProp.c
       
   270 index 8667350..bde6cb5 100644
       
   271 --- a/src/XListDProp.c
       
   272 +++ b/src/XListDProp.c
       
   273 @@ -65,7 +65,7 @@ XListDeviceProperties(Display* dpy, XDevice* dev, int *nprops_return)
       
   274          props = (Atom*)Xmalloc(rep.nAtoms * sizeof(Atom));
       
   275          if (!props)
       
   276          {
       
   277 -            _XEatData(dpy, rep.nAtoms << 2);
       
   278 +            _XEatDataWords(dpy, rep.length);
       
   279              goto cleanup;
       
   280          }
       
   281  
       
   282 diff --git a/src/XListDev.c b/src/XListDev.c
       
   283 index bd6e70a..1fa4747 100644
       
   284 --- a/src/XListDev.c
       
   285 +++ b/src/XListDev.c
       
   286 @@ -202,7 +202,7 @@ XListInputDevices(
       
   287  	list = (xDeviceInfo *) Xmalloc(rlen);
       
   288  	slist = list;
       
   289  	if (!slist) {
       
   290 -	    _XEatData(dpy, (unsigned long)rlen);
       
   291 +	    _XEatDataWords(dpy, rep.length);
       
   292  	    UnlockDisplay(dpy);
       
   293  	    SyncHandle();
       
   294  	    return (XDeviceInfo *) NULL;
       
   295 diff --git a/src/XOpenDev.c b/src/XOpenDev.c
       
   296 index 74f18ac..e784f8b 100644
       
   297 --- a/src/XOpenDev.c
       
   298 +++ b/src/XOpenDev.c
       
   299 @@ -101,7 +101,7 @@ XOpenDevice(
       
   300  	if (rlen - dlen > 0)
       
   301  	    _XEatData(dpy, (unsigned long)rlen - dlen);
       
   302      } else
       
   303 -	_XEatData(dpy, (unsigned long)rlen);
       
   304 +	_XEatDataWords(dpy, rep.length);
       
   305  
       
   306      UnlockDisplay(dpy);
       
   307      SyncHandle();
       
   308 diff --git a/src/XQueryDv.c b/src/XQueryDv.c
       
   309 index 24d4e4e..69c285b 100644
       
   310 --- a/src/XQueryDv.c
       
   311 +++ b/src/XQueryDv.c
       
   312 @@ -91,7 +91,7 @@ XQueryDeviceState(
       
   313      if (rlen > 0) {
       
   314  	data = Xmalloc(rlen);
       
   315  	if (!data) {
       
   316 -	    _XEatData(dpy, (unsigned long)rlen);
       
   317 +	    _XEatDataWords(dpy, rep.length);
       
   318  	    goto out;
       
   319  	}
       
   320  	_XRead(dpy, data, rlen);
       
   321 -- 
       
   322 1.7.9.2
       
   323 
       
   324 From 0acd07e1c9583e2e7c26c13f8628bde992d9bce5 Mon Sep 17 00:00:00 2001
       
   325 From: Alan Coopersmith <[email protected]>
       
   326 Date: Sat, 9 Mar 2013 22:26:52 -0800
       
   327 Subject: [PATCH:libXi 02/13] Stack buffer overflow in
       
   328  XGetDeviceButtonMapping() [CVE-2013-1998 1/3]
       
   329 
       
   330 We copy the entire reply sent by the server into the fixed size
       
   331 mapping[] array on the stack, even if the server says it's a larger
       
   332 size than the mapping array can hold.  HULK SMASH STACK!
       
   333 
       
   334 Reported-by: Ilja Van Sprundel <[email protected]>
       
   335 Signed-off-by: Alan Coopersmith <[email protected]>
       
   336 Reviewed-by: Peter Hutterer <[email protected]>
       
   337 ---
       
   338  src/XGetBMap.c |   21 +++++++++++++--------
       
   339  1 file changed, 13 insertions(+), 8 deletions(-)
       
   340 
       
   341 diff --git a/src/XGetBMap.c b/src/XGetBMap.c
       
   342 index 211c9ca..002daba 100644
       
   343 --- a/src/XGetBMap.c
       
   344 +++ b/src/XGetBMap.c
       
   345 @@ -60,6 +60,7 @@ SOFTWARE.
       
   346  #include <X11/extensions/XInput.h>
       
   347  #include <X11/extensions/extutil.h>
       
   348  #include "XIint.h"
       
   349 +#include <limits.h>
       
   350  
       
   351  #ifdef MIN	/* some systems define this in <sys/param.h> */
       
   352  #undef MIN
       
   353 @@ -75,7 +76,6 @@ XGetDeviceButtonMapping(
       
   354  {
       
   355      int status = 0;
       
   356      unsigned char mapping[256];	/* known fixed size */
       
   357 -    long nbytes;
       
   358      XExtDisplayInfo *info = XInput_find_display(dpy);
       
   359  
       
   360      register xGetDeviceButtonMappingReq *req;
       
   361 @@ -92,13 +92,18 @@ XGetDeviceButtonMapping(
       
   362  
       
   363      status = _XReply(dpy, (xReply *) & rep, 0, xFalse);
       
   364      if (status == 1) {
       
   365 -	nbytes = (long)rep.length << 2;
       
   366 -	_XRead(dpy, (char *)mapping, nbytes);
       
   367 -
       
   368 -	/* don't return more data than the user asked for. */
       
   369 -	if (rep.nElts)
       
   370 -	    memcpy((char *)map, (char *)mapping, MIN((int)rep.nElts, nmap));
       
   371 -	status = rep.nElts;
       
   372 +	if (rep.length <= (sizeof(mapping) >> 2)) {
       
   373 +	    unsigned long nbytes = rep.length << 2;
       
   374 +	    _XRead(dpy, (char *)mapping, nbytes);
       
   375 +
       
   376 +	    /* don't return more data than the user asked for. */
       
   377 +	    if (rep.nElts)
       
   378 +		memcpy(map, mapping, MIN((int)rep.nElts, nmap));
       
   379 +	    status = rep.nElts;
       
   380 +	} else {
       
   381 +	    _XEatDataWords(dpy, rep.length);
       
   382 +	    status = 0;
       
   383 +	}
       
   384      } else
       
   385  	status = 0;
       
   386      UnlockDisplay(dpy);
       
   387 -- 
       
   388 1.7.9.2
       
   389 
       
   390 From 18855aa8c261863c00690b7df1e5ce4660687fb6 Mon Sep 17 00:00:00 2001
       
   391 From: Alan Coopersmith <[email protected]>
       
   392 Date: Sat, 9 Mar 2013 23:37:23 -0800
       
   393 Subject: [PATCH:libXi 03/13] memory corruption in _XIPassiveGrabDevice()
       
   394  [CVE-2013-1998 2/3]
       
   395 
       
   396 If the server returned more modifiers than the caller asked for,
       
   397 we'd just keep copying past the end of the array provided by the
       
   398 caller, writing over who-knows-what happened to be there.
       
   399 
       
   400 Signed-off-by: Alan Coopersmith <[email protected]>
       
   401 Reviewed-by: Peter Hutterer <[email protected]>
       
   402 ---
       
   403  src/XIPassiveGrab.c |    2 +-
       
   404  1 file changed, 1 insertion(+), 1 deletion(-)
       
   405 
       
   406 diff --git a/src/XIPassiveGrab.c b/src/XIPassiveGrab.c
       
   407 index ac17c01..53b4084 100644
       
   408 --- a/src/XIPassiveGrab.c
       
   409 +++ b/src/XIPassiveGrab.c
       
   410 @@ -88,7 +88,7 @@ _XIPassiveGrabDevice(Display* dpy, int deviceid, int grabtype, int detail,
       
   411          return -1;
       
   412      _XRead(dpy, (char*)failed_mods, reply.num_modifiers * sizeof(xXIGrabModifierInfo));
       
   413  
       
   414 -    for (i = 0; i < reply.num_modifiers; i++)
       
   415 +    for (i = 0; i < reply.num_modifiers && i < num_modifiers; i++)
       
   416      {
       
   417          modifiers_inout[i].status = failed_mods[i].status;
       
   418          modifiers_inout[i].modifiers = failed_mods[i].modifiers;
       
   419 -- 
       
   420 1.7.9.2
       
   421 
       
   422 From a74690ba880036e01fc39f522b7567daf3746a31 Mon Sep 17 00:00:00 2001
       
   423 From: Alan Coopersmith <[email protected]>
       
   424 Date: Fri, 26 Apr 2013 22:48:36 -0700
       
   425 Subject: [PATCH:libXi 04/13] unvalidated lengths in XQueryDeviceState()
       
   426  [CVE-2013-1998 3/3]
       
   427 
       
   428 If the lengths given for each class state in the reply add up to more
       
   429 than the rep.length, we could read past the end of the buffer allocated
       
   430 to hold the data read from the server.
       
   431 
       
   432 Signed-off-by: Alan Coopersmith <[email protected]>
       
   433 Reviewed-by: Peter Hutterer <[email protected]>
       
   434 ---
       
   435  src/XQueryDv.c |   17 ++++++++++++-----
       
   436  1 file changed, 12 insertions(+), 5 deletions(-)
       
   437 
       
   438 diff --git a/src/XQueryDv.c b/src/XQueryDv.c
       
   439 index 69c285b..3836777 100644
       
   440 --- a/src/XQueryDv.c
       
   441 +++ b/src/XQueryDv.c
       
   442 @@ -59,6 +59,7 @@ SOFTWARE.
       
   443  #include <X11/extensions/XInput.h>
       
   444  #include <X11/extensions/extutil.h>
       
   445  #include "XIint.h"
       
   446 +#include <limits.h>
       
   447  
       
   448  XDeviceState *
       
   449  XQueryDeviceState(
       
   450 @@ -66,8 +67,8 @@ XQueryDeviceState(
       
   451      XDevice		*dev)
       
   452  {
       
   453      int i, j;
       
   454 -    int rlen;
       
   455 -    int size = 0;
       
   456 +    unsigned long rlen;
       
   457 +    size_t size = 0;
       
   458      xQueryDeviceStateReq *req;
       
   459      xQueryDeviceStateReply rep;
       
   460      XDeviceState *state = NULL;
       
   461 @@ -87,9 +88,11 @@ XQueryDeviceState(
       
   462      if (!_XReply(dpy, (xReply *) & rep, 0, xFalse))
       
   463          goto out;
       
   464  
       
   465 -    rlen = rep.length << 2;
       
   466 -    if (rlen > 0) {
       
   467 -	data = Xmalloc(rlen);
       
   468 +    if (rep.length > 0) {
       
   469 +	if (rep.length < (INT_MAX >> 2)) {
       
   470 +	    rlen = (unsigned long) rep.length << 2;
       
   471 +	    data = Xmalloc(rlen);
       
   472 +	}
       
   473  	if (!data) {
       
   474  	    _XEatDataWords(dpy, rep.length);
       
   475  	    goto out;
       
   476 @@ -97,6 +100,10 @@ XQueryDeviceState(
       
   477  	_XRead(dpy, data, rlen);
       
   478  
       
   479  	for (i = 0, any = (XInputClass *) data; i < (int)rep.num_classes; i++) {
       
   480 +	    if (any->length > rlen)
       
   481 +		goto out;
       
   482 +	    rlen -= any->length;
       
   483 +
       
   484  	    switch (any->class) {
       
   485  	    case KeyClass:
       
   486  		size += sizeof(XKeyState);
       
   487 -- 
       
   488 1.7.9.2
       
   489 
       
   490 From 38b563078ee050086526294f42f9f162be4bf97d Mon Sep 17 00:00:00 2001
       
   491 From: Alan Coopersmith <[email protected]>
       
   492 Date: Sat, 9 Mar 2013 22:55:23 -0800
       
   493 Subject: [PATCH:libXi 05/13] integer overflow in XGetDeviceControl()
       
   494  [CVE-2013-1984 1/8]
       
   495 
       
   496 If the number of valuators reported by the server is large enough that
       
   497 it overflows when multiplied by the size of the appropriate struct, then
       
   498 memory corruption can occur when more bytes are copied from the X server
       
   499 reply than the size of the buffer we allocated to hold them.
       
   500 
       
   501 v2: check that reply size fits inside the data read from the server, so
       
   502 we don't read out of bounds either
       
   503 
       
   504 Reported-by: Ilja Van Sprundel <[email protected]>
       
   505 Signed-off-by: Alan Coopersmith <[email protected]>
       
   506 Reviewed-by: Peter Hutterer <[email protected]>
       
   507 ---
       
   508  src/XGetDCtl.c |   31 ++++++++++++++++++++++++-------
       
   509  1 file changed, 24 insertions(+), 7 deletions(-)
       
   510 
       
   511 diff --git a/src/XGetDCtl.c b/src/XGetDCtl.c
       
   512 index f73a4e8..51ed0ae 100644
       
   513 --- a/src/XGetDCtl.c
       
   514 +++ b/src/XGetDCtl.c
       
   515 @@ -61,6 +61,7 @@ SOFTWARE.
       
   516  #include <X11/extensions/XInput.h>
       
   517  #include <X11/extensions/extutil.h>
       
   518  #include "XIint.h"
       
   519 +#include <limits.h>
       
   520  
       
   521  XDeviceControl *
       
   522  XGetDeviceControl(
       
   523 @@ -68,8 +69,6 @@ XGetDeviceControl(
       
   524      XDevice		*dev,
       
   525      int			 control)
       
   526  {
       
   527 -    int size = 0;
       
   528 -    int nbytes, i;
       
   529      XDeviceControl *Device = NULL;
       
   530      XDeviceControl *Sav = NULL;
       
   531      xDeviceState *d = NULL;
       
   532 @@ -92,8 +91,12 @@ XGetDeviceControl(
       
   533  	goto out;
       
   534  
       
   535      if (rep.length > 0) {
       
   536 -	nbytes = (long)rep.length << 2;
       
   537 -	d = (xDeviceState *) Xmalloc((unsigned)nbytes);
       
   538 +	unsigned long nbytes;
       
   539 +	size_t size = 0;
       
   540 +	if (rep.length < (INT_MAX >> 2)) {
       
   541 +	    nbytes = (unsigned long) rep.length << 2;
       
   542 +	    d = Xmalloc(nbytes);
       
   543 +	}
       
   544  	if (!d) {
       
   545  	    _XEatDataWords(dpy, rep.length);
       
   546  	    goto out;
       
   547 @@ -111,33 +114,46 @@ XGetDeviceControl(
       
   548  	case DEVICE_RESOLUTION:
       
   549  	{
       
   550  	    xDeviceResolutionState *r;
       
   551 +	    size_t val_size;
       
   552  
       
   553  	    r = (xDeviceResolutionState *) d;
       
   554 -	    size += sizeof(XDeviceResolutionState) +
       
   555 -		(3 * sizeof(int) * r->num_valuators);
       
   556 +	    if (r->num_valuators >= (INT_MAX / (3 * sizeof(int))))
       
   557 +		goto out;
       
   558 +	    val_size = 3 * sizeof(int) * r->num_valuators;
       
   559 +	    if ((sizeof(xDeviceResolutionState) + val_size) > nbytes)
       
   560 +		goto out;
       
   561 +	    size += sizeof(XDeviceResolutionState) + val_size;
       
   562  	    break;
       
   563  	}
       
   564          case DEVICE_ABS_CALIB:
       
   565          {
       
   566 +            if (sizeof(xDeviceAbsCalibState) > nbytes)
       
   567 +                goto out;
       
   568              size += sizeof(XDeviceAbsCalibState);
       
   569              break;
       
   570          }
       
   571          case DEVICE_ABS_AREA:
       
   572          {
       
   573 +            if (sizeof(xDeviceAbsAreaState) > nbytes)
       
   574 +                goto out;
       
   575              size += sizeof(XDeviceAbsAreaState);
       
   576              break;
       
   577          }
       
   578          case DEVICE_CORE:
       
   579          {
       
   580 +            if (sizeof(xDeviceCoreState) > nbytes)
       
   581 +                goto out;
       
   582              size += sizeof(XDeviceCoreState);
       
   583              break;
       
   584          }
       
   585  	default:
       
   586 +	    if (d->length > nbytes)
       
   587 +		goto out;
       
   588  	    size += d->length;
       
   589  	    break;
       
   590  	}
       
   591  
       
   592 -	Device = (XDeviceControl *) Xmalloc((unsigned)size);
       
   593 +	Device = Xmalloc(size);
       
   594  	if (!Device)
       
   595  	    goto out;
       
   596  
       
   597 @@ -150,6 +166,7 @@ XGetDeviceControl(
       
   598  	    int *iptr, *iptr2;
       
   599  	    xDeviceResolutionState *r;
       
   600  	    XDeviceResolutionState *R;
       
   601 +	    unsigned int i;
       
   602  
       
   603  	    r = (xDeviceResolutionState *) d;
       
   604  	    R = (XDeviceResolutionState *) Device;
       
   605 -- 
       
   606 1.7.9.2
       
   607 
       
   608 From 9e39ad6e66a517c2324426c3aa32f4cfcc1cd4f5 Mon Sep 17 00:00:00 2001
       
   609 From: Alan Coopersmith <[email protected]>
       
   610 Date: Sat, 9 Mar 2013 22:55:23 -0800
       
   611 Subject: [PATCH:libXi 06/13] integer overflow in XGetFeedbackControl()
       
   612  [CVE-2013-1984 2/8]
       
   613 
       
   614 If the number of feedbacks reported by the server is large enough that
       
   615 it overflows when multiplied by the size of the appropriate struct, or
       
   616 if the total size of all the feedback structures overflows when added
       
   617 together, then memory corruption can occur when more bytes are copied from
       
   618 the X server reply than the size of the buffer we allocated to hold them.
       
   619 
       
   620 v2: check that reply size fits inside the data read from the server, so
       
   621     we don't read out of bounds either
       
   622 
       
   623 Reported-by: Ilja Van Sprundel <[email protected]>
       
   624 Signed-off-by: Alan Coopersmith <[email protected]>
       
   625 Reviewed-by: Peter Hutterer <[email protected]>
       
   626 ---
       
   627  src/XGetFCtl.c |   24 +++++++++++++++++++-----
       
   628  1 file changed, 19 insertions(+), 5 deletions(-)
       
   629 
       
   630 diff --git a/src/XGetFCtl.c b/src/XGetFCtl.c
       
   631 index 28fab4d..bb50bf3 100644
       
   632 --- a/src/XGetFCtl.c
       
   633 +++ b/src/XGetFCtl.c
       
   634 @@ -61,6 +61,7 @@ SOFTWARE.
       
   635  #include <X11/extensions/XInput.h>
       
   636  #include <X11/extensions/extutil.h>
       
   637  #include "XIint.h"
       
   638 +#include <limits.h>
       
   639  
       
   640  XFeedbackState *
       
   641  XGetFeedbackControl(
       
   642 @@ -68,8 +69,6 @@ XGetFeedbackControl(
       
   643      XDevice		*dev,
       
   644      int			*num_feedbacks)
       
   645  {
       
   646 -    int size = 0;
       
   647 -    int nbytes, i;
       
   648      XFeedbackState *Feedback = NULL;
       
   649      XFeedbackState *Sav = NULL;
       
   650      xFeedbackState *f = NULL;
       
   651 @@ -91,9 +90,16 @@ XGetFeedbackControl(
       
   652  	goto out;
       
   653  
       
   654      if (rep.length > 0) {
       
   655 +	unsigned long nbytes;
       
   656 +	size_t size = 0;
       
   657 +	int i;
       
   658 +
       
   659  	*num_feedbacks = rep.num_feedbacks;
       
   660 -	nbytes = (long)rep.length << 2;
       
   661 -	f = (xFeedbackState *) Xmalloc((unsigned)nbytes);
       
   662 +
       
   663 +	if (rep.length < (INT_MAX >> 2)) {
       
   664 +	    nbytes = rep.length << 2;
       
   665 +	    f = Xmalloc(nbytes);
       
   666 +	}
       
   667  	if (!f) {
       
   668  	    _XEatDataWords(dpy, rep.length);
       
   669  	    goto out;
       
   670 @@ -102,6 +108,10 @@ XGetFeedbackControl(
       
   671  	_XRead(dpy, (char *)f, nbytes);
       
   672  
       
   673  	for (i = 0; i < *num_feedbacks; i++) {
       
   674 +	    if (f->length > nbytes)
       
   675 +		goto out;
       
   676 +	    nbytes -= f->length;
       
   677 +
       
   678  	    switch (f->class) {
       
   679  	    case KbdFeedbackClass:
       
   680  		size += sizeof(XKbdFeedbackState);
       
   681 @@ -116,6 +126,8 @@ XGetFeedbackControl(
       
   682  	    {
       
   683  		xStringFeedbackState *strf = (xStringFeedbackState *) f;
       
   684  
       
   685 +		if (strf->num_syms_supported >= (INT_MAX / sizeof(KeySym)))
       
   686 +		    goto out;
       
   687  		size += sizeof(XStringFeedbackState) +
       
   688  		    (strf->num_syms_supported * sizeof(KeySym));
       
   689  	    }
       
   690 @@ -130,10 +142,12 @@ XGetFeedbackControl(
       
   691  		size += f->length;
       
   692  		break;
       
   693  	    }
       
   694 +	    if (size > INT_MAX)
       
   695 +		goto out;
       
   696  	    f = (xFeedbackState *) ((char *)f + f->length);
       
   697  	}
       
   698  
       
   699 -	Feedback = (XFeedbackState *) Xmalloc((unsigned)size);
       
   700 +	Feedback = Xmalloc(size);
       
   701  	if (!Feedback)
       
   702  	    goto out;
       
   703  
       
   704 -- 
       
   705 1.7.9.2
       
   706 
       
   707 From 0bb14773ba37dfa8098b3e1784c80658019f9f21 Mon Sep 17 00:00:00 2001
       
   708 From: Alan Coopersmith <[email protected]>
       
   709 Date: Sat, 9 Mar 2013 22:55:23 -0800
       
   710 Subject: [PATCH:libXi 07/13] integer overflow in
       
   711  XGetDeviceDontPropagateList() [CVE-2013-1984
       
   712  3/8]
       
   713 
       
   714 If the number of event classes reported by the server is large enough
       
   715 that it overflows when multiplied by the size of the appropriate struct,
       
   716 then memory corruption can occur when more bytes are copied from the
       
   717 X server reply than the size of the buffer we allocated to hold them.
       
   718 
       
   719 V2: EatData if count is 0 but length is > 0 to avoid XIOErrors
       
   720 
       
   721 Reported-by: Ilja Van Sprundel <[email protected]>
       
   722 Signed-off-by: Alan Coopersmith <[email protected]>
       
   723 Reviewed-by: Peter Hutterer <[email protected]>
       
   724 ---
       
   725  src/XGetProp.c |    8 +++++---
       
   726  1 file changed, 5 insertions(+), 3 deletions(-)
       
   727 
       
   728 diff --git a/src/XGetProp.c b/src/XGetProp.c
       
   729 index 34bc581..b49328c 100644
       
   730 --- a/src/XGetProp.c
       
   731 +++ b/src/XGetProp.c
       
   732 @@ -60,6 +60,7 @@ SOFTWARE.
       
   733  #include <X11/extensions/XInput.h>
       
   734  #include <X11/extensions/extutil.h>
       
   735  #include "XIint.h"
       
   736 +#include <limits.h>
       
   737  
       
   738  XEventClass *
       
   739  XGetDeviceDontPropagateList(
       
   740 @@ -88,10 +89,11 @@ XGetDeviceDontPropagateList(
       
   741      }
       
   742      *count = rep.count;
       
   743  
       
   744 -    if (*count) {
       
   745 -	list = (XEventClass *) Xmalloc(rep.length * sizeof(XEventClass));
       
   746 +    if (rep.length != 0) {
       
   747 +	if ((rep.count != 0) && (rep.length < (INT_MAX / sizeof(XEventClass))))
       
   748 +	    list = Xmalloc(rep.length * sizeof(XEventClass));
       
   749  	if (list) {
       
   750 -	    int i;
       
   751 +	    unsigned int i;
       
   752  	    CARD32 ec;
       
   753  
       
   754  	    /* read and assign each XEventClass separately because
       
   755 -- 
       
   756 1.7.9.2
       
   757 
       
   758 From 3d1fc7cd03e9a41b86cd83a8922df551a1b87179 Mon Sep 17 00:00:00 2001
       
   759 From: Alan Coopersmith <[email protected]>
       
   760 Date: Sat, 9 Mar 2013 22:55:23 -0800
       
   761 Subject: [PATCH:libXi 08/13] integer overflow in XGetDeviceMotionEvents()
       
   762  [CVE-2013-1984 4/8]
       
   763 
       
   764 If the number of events or axes reported by the server is large enough
       
   765 that it overflows when multiplied by the size of the appropriate struct,
       
   766 then memory corruption can occur when more bytes are copied from the
       
   767 X server reply than the size of the buffer we allocated to hold them.
       
   768 
       
   769 Reported-by: Ilja Van Sprundel <[email protected]>
       
   770 Signed-off-by: Alan Coopersmith <[email protected]>
       
   771 Reviewed-by: Peter Hutterer <[email protected]>
       
   772 ---
       
   773  src/XGMotion.c |   22 +++++++++++++++++-----
       
   774  1 file changed, 17 insertions(+), 5 deletions(-)
       
   775 
       
   776 diff --git a/src/XGMotion.c b/src/XGMotion.c
       
   777 index 5feac85..a4c75b6 100644
       
   778 --- a/src/XGMotion.c
       
   779 +++ b/src/XGMotion.c
       
   780 @@ -59,6 +59,7 @@ SOFTWARE.
       
   781  #include <X11/extensions/XInput.h>
       
   782  #include <X11/extensions/extutil.h>
       
   783  #include "XIint.h"
       
   784 +#include <limits.h>
       
   785  
       
   786  XDeviceTimeCoord *
       
   787  XGetDeviceMotionEvents(
       
   788 @@ -74,7 +75,7 @@ XGetDeviceMotionEvents(
       
   789      xGetDeviceMotionEventsReply rep;
       
   790      XDeviceTimeCoord *tc;
       
   791      int *data, *bufp, *readp, *savp;
       
   792 -    long size, size2;
       
   793 +    unsigned long size;
       
   794      int i, j;
       
   795      XExtDisplayInfo *info = XInput_find_display(dpy);
       
   796  
       
   797 @@ -104,10 +105,21 @@ XGetDeviceMotionEvents(
       
   798  	SyncHandle();
       
   799  	return (NULL);
       
   800      }
       
   801 -    size = rep.length << 2;
       
   802 -    size2 = rep.nEvents * (sizeof(XDeviceTimeCoord) + (rep.axes * sizeof(int)));
       
   803 -    savp = readp = (int *)Xmalloc(size);
       
   804 -    bufp = (int *)Xmalloc(size2);
       
   805 +    if (rep.length < (INT_MAX >> 2)) {
       
   806 +	size = rep.length << 2;
       
   807 +	savp = readp = Xmalloc(size);
       
   808 +    } else {
       
   809 +	size = 0;
       
   810 +	savp = readp = NULL;
       
   811 +    }
       
   812 +    /* rep.axes is a CARD8, so assume max number of axes for bounds check */
       
   813 +    if (rep.nEvents <
       
   814 +	(INT_MAX / (sizeof(XDeviceTimeCoord) + (UCHAR_MAX * sizeof(int))))) {
       
   815 +	size_t bsize = rep.nEvents *
       
   816 +	    (sizeof(XDeviceTimeCoord) + (rep.axes * sizeof(int)));
       
   817 +	bufp = Xmalloc(bsize);
       
   818 +    } else
       
   819 +	bufp = NULL;
       
   820      if (!bufp || !savp) {
       
   821  	Xfree(bufp);
       
   822  	Xfree(savp);
       
   823 -- 
       
   824 1.7.9.2
       
   825 
       
   826 From 1202a8fc208581e184d327118a8a8ac3a27bbe64 Mon Sep 17 00:00:00 2001
       
   827 From: Alan Coopersmith <[email protected]>
       
   828 Date: Sat, 9 Mar 2013 22:55:23 -0800
       
   829 Subject: [PATCH:libXi 09/13] integer overflow in XIGetProperty()
       
   830  [CVE-2013-1984 5/8]
       
   831 
       
   832 If the number of items reported by the server is large enough that
       
   833 it overflows when multiplied by the size of the appropriate item type,
       
   834 then memory corruption can occur when more bytes are copied from the
       
   835 X server reply than the size of the buffer we allocated to hold them.
       
   836 
       
   837 Reported-by: Ilja Van Sprundel <[email protected]>
       
   838 Signed-off-by: Alan Coopersmith <[email protected]>
       
   839 Reviewed-by: Peter Hutterer <[email protected]>
       
   840 ---
       
   841  src/XIProperties.c |   11 +++++++----
       
   842  1 file changed, 7 insertions(+), 4 deletions(-)
       
   843 
       
   844 diff --git a/src/XIProperties.c b/src/XIProperties.c
       
   845 index 5e58fb6..32436d1 100644
       
   846 --- a/src/XIProperties.c
       
   847 +++ b/src/XIProperties.c
       
   848 @@ -38,6 +38,7 @@
       
   849  #include <X11/extensions/XInput2.h>
       
   850  #include <X11/extensions/extutil.h>
       
   851  #include "XIint.h"
       
   852 +#include <limits.h>
       
   853  
       
   854  Atom*
       
   855  XIListProperties(Display* dpy, int deviceid, int *num_props_return)
       
   856 @@ -170,7 +171,7 @@ XIGetProperty(Display* dpy, int deviceid, Atom property, long offset,
       
   857  {
       
   858      xXIGetPropertyReq   *req;
       
   859      xXIGetPropertyReply rep;
       
   860 -    long                    nbytes, rbytes;
       
   861 +    unsigned long       nbytes, rbytes;
       
   862  
       
   863      XExtDisplayInfo *info = XInput_find_display(dpy);
       
   864  
       
   865 @@ -216,9 +217,11 @@ XIGetProperty(Display* dpy, int deviceid, Atom property, long offset,
       
   866  	 * recopy the string to make it null terminated.
       
   867  	 */
       
   868  
       
   869 -        nbytes = rep.num_items * rep.format/8;
       
   870 -        rbytes = nbytes + 1;
       
   871 -        *data = Xmalloc(rbytes);
       
   872 +	if (rep.num_items < (INT_MAX / (rep.format/8))) {
       
   873 +	    nbytes = rep.num_items * rep.format/8;
       
   874 +	    rbytes = nbytes + 1;
       
   875 +	    *data = Xmalloc(rbytes);
       
   876 +	}
       
   877  
       
   878  	if (!(*data)) {
       
   879  	    _XEatDataWords(dpy, rep.length);
       
   880 -- 
       
   881 1.7.9.2
       
   882 
       
   883 From a3e76afd699b7afa590c8d3567663460c9870924 Mon Sep 17 00:00:00 2001
       
   884 From: Alan Coopersmith <[email protected]>
       
   885 Date: Sat, 9 Mar 2013 22:55:23 -0800
       
   886 Subject: [PATCH:libXi 10/13] integer overflow in XIGetSelectedEvents()
       
   887  [CVE-2013-1984 6/8]
       
   888 
       
   889 If the number of events or masks reported by the server is large enough
       
   890 that it overflows when multiplied by the size of the appropriate struct,
       
   891 or the sizes overflow as they are totaled up, then memory corruption can
       
   892 occur when more bytes are copied from the X server reply than the size
       
   893 of the buffer we allocated to hold them.
       
   894 
       
   895 v2: check that reply size fits inside the data read from the server,
       
   896     so that we don't read out of bounds either
       
   897 
       
   898 Reported-by: Ilja Van Sprundel <[email protected]>
       
   899 Signed-off-by: Alan Coopersmith <[email protected]>
       
   900 Reviewed-by: Peter Hutterer <[email protected]>
       
   901 ---
       
   902  src/XISelEv.c |   25 +++++++++++++++++++------
       
   903  1 file changed, 19 insertions(+), 6 deletions(-)
       
   904 
       
   905 diff --git a/src/XISelEv.c b/src/XISelEv.c
       
   906 index f871222..0471bef 100644
       
   907 --- a/src/XISelEv.c
       
   908 +++ b/src/XISelEv.c
       
   909 @@ -42,6 +42,7 @@ in this Software without prior written authorization from the author.
       
   910  #include <X11/extensions/ge.h>
       
   911  #include <X11/extensions/geproto.h>
       
   912  #include "XIint.h"
       
   913 +#include <limits.h>
       
   914  
       
   915  int
       
   916  XISelectEvents(Display* dpy, Window win, XIEventMask* masks, int num_masks)
       
   917 @@ -101,13 +102,14 @@ out:
       
   918  XIEventMask*
       
   919  XIGetSelectedEvents(Display* dpy, Window win, int *num_masks_return)
       
   920  {
       
   921 -    int i, len = 0;
       
   922 +    unsigned int i, len = 0;
       
   923      unsigned char *mask;
       
   924      XIEventMask *mask_out = NULL;
       
   925      xXIEventMask *mask_in = NULL, *mi;
       
   926      xXIGetSelectedEventsReq *req;
       
   927      xXIGetSelectedEventsReply reply;
       
   928      XExtDisplayInfo *info = XInput_find_display(dpy);
       
   929 +    size_t rbytes;
       
   930  
       
   931      *num_masks_return = -1;
       
   932      LockDisplay(dpy);
       
   933 @@ -129,11 +131,16 @@ XIGetSelectedEvents(Display* dpy, Window win, int *num_masks_return)
       
   934          goto out;
       
   935      }
       
   936  
       
   937 -    mask_in = Xmalloc(reply.length * 4);
       
   938 -    if (!mask_in)
       
   939 +    if (reply.length < (INT_MAX >> 2)) {
       
   940 +        rbytes = (unsigned long) reply.length << 2;
       
   941 +        mask_in = Xmalloc(rbytes);
       
   942 +    }
       
   943 +    if (!mask_in) {
       
   944 +        _XEatDataWords(dpy, reply.length);
       
   945          goto out;
       
   946 +    }
       
   947  
       
   948 -    _XRead(dpy, (char*)mask_in, reply.length * 4);
       
   949 +    _XRead(dpy, (char*)mask_in, rbytes);
       
   950  
       
   951      /*
       
   952       * This function takes interleaved xXIEventMask structs & masks off
       
   953 @@ -148,8 +155,14 @@ XIGetSelectedEvents(Display* dpy, Window win, int *num_masks_return)
       
   954  
       
   955      for (i = 0, mi = mask_in; i < reply.num_masks; i++)
       
   956      {
       
   957 -        len += mi->mask_len * 4;
       
   958 -        mi = (xXIEventMask*)((char*)mi + mi->mask_len * 4);
       
   959 +        unsigned int mask_bytes = mi->mask_len * 4;
       
   960 +        len += mask_bytes;
       
   961 +        if (len > INT_MAX)
       
   962 +            goto out;
       
   963 +        if ((sizeof(xXIEventMask) + mask_bytes) > rbytes)
       
   964 +            goto out;
       
   965 +        rbytes -= (sizeof(xXIEventMask) + mask_bytes);
       
   966 +        mi = (xXIEventMask*)((char*)mi + mask_bytes);
       
   967          mi++;
       
   968      }
       
   969  
       
   970 -- 
       
   971 1.7.9.2
       
   972 
       
   973 From b6246afd838842d28ac94d901507390624f31c7d Mon Sep 17 00:00:00 2001
       
   974 From: Alan Coopersmith <[email protected]>
       
   975 Date: Sun, 10 Mar 2013 13:30:55 -0700
       
   976 Subject: [PATCH:libXi 11/13] Avoid integer overflow in XGetDeviceProperties()
       
   977  [CVE-2013-1984 7/8]
       
   978 
       
   979 If the number of items as reported by the Xserver is too large, it
       
   980 could overflow the calculation for the size of the buffer to copy the
       
   981 reply into, causing memory corruption.
       
   982 
       
   983 Signed-off-by: Alan Coopersmith <[email protected]>
       
   984 Reviewed-by: Peter Hutterer <[email protected]>
       
   985 ---
       
   986  src/XGetDProp.c |   61 +++++++++++++++++++++++++++++++++----------------------
       
   987  1 file changed, 37 insertions(+), 24 deletions(-)
       
   988 
       
   989 diff --git a/src/XGetDProp.c b/src/XGetDProp.c
       
   990 index f9e8f0c..3691122 100644
       
   991 --- a/src/XGetDProp.c
       
   992 +++ b/src/XGetDProp.c
       
   993 @@ -38,6 +38,7 @@ in this Software without prior written authorization from the author.
       
   994  #include <X11/extensions/XInput.h>
       
   995  #include <X11/extensions/extutil.h>
       
   996  #include "XIint.h"
       
   997 +#include <limits.h>
       
   998  
       
   999  int
       
  1000  XGetDeviceProperty(Display* dpy, XDevice* dev,
       
  1001 @@ -48,7 +49,8 @@ XGetDeviceProperty(Display* dpy, XDevice* dev,
       
  1002  {
       
  1003      xGetDevicePropertyReq   *req;
       
  1004      xGetDevicePropertyReply rep;
       
  1005 -    long                    nbytes, rbytes;
       
  1006 +    unsigned long           nbytes, rbytes;
       
  1007 +    int                     ret = Success;
       
  1008  
       
  1009      XExtDisplayInfo *info = XInput_find_display(dpy);
       
  1010  
       
  1011 @@ -81,30 +83,43 @@ XGetDeviceProperty(Display* dpy, XDevice* dev,
       
  1012  	 * data, but this last byte is null terminated and convenient for
       
  1013  	 * returning string properties, so the client doesn't then have to
       
  1014  	 * recopy the string to make it null terminated.
       
  1015 +	 *
       
  1016 +	 * Maximum item limits are set to both prevent integer overflow when
       
  1017 +	 * calculating the amount of memory to malloc, and to limit how much
       
  1018 +	 * memory will be used if a server provides an insanely high count.
       
  1019  	 */
       
  1020  	switch (rep.format) {
       
  1021  	case 8:
       
  1022 -	    nbytes = rep.nItems;
       
  1023 -	    rbytes = rep.nItems + 1;
       
  1024 -	    if (rbytes > 0 &&
       
  1025 -		(*prop = (unsigned char *) Xmalloc ((unsigned)rbytes)))
       
  1026 -		_XReadPad (dpy, (char *) *prop, nbytes);
       
  1027 +	    if (rep.nItems < INT_MAX) {
       
  1028 +		nbytes = rep.nItems;
       
  1029 +		rbytes = rep.nItems + 1;
       
  1030 +		if ((*prop = Xmalloc (rbytes)))
       
  1031 +		    _XReadPad (dpy, (char *) *prop, nbytes);
       
  1032 +		else
       
  1033 +		    ret = BadAlloc;
       
  1034 +	    }
       
  1035  	    break;
       
  1036  
       
  1037  	case 16:
       
  1038 -	    nbytes = rep.nItems << 1;
       
  1039 -	    rbytes = rep.nItems * sizeof (short) + 1;
       
  1040 -	    if (rbytes > 0 &&
       
  1041 -		(*prop = (unsigned char *) Xmalloc ((unsigned)rbytes)))
       
  1042 -		_XRead16Pad (dpy, (short *) *prop, nbytes);
       
  1043 +	    if (rep.nItems < (INT_MAX / sizeof (short))) {
       
  1044 +		nbytes = rep.nItems << 1;
       
  1045 +		rbytes = rep.nItems * sizeof (short) + 1;
       
  1046 +		if ((*prop = Xmalloc (rbytes)))
       
  1047 +		    _XRead16Pad (dpy, (short *) *prop, nbytes);
       
  1048 +		else
       
  1049 +		    ret = BadAlloc;
       
  1050 +	    }
       
  1051  	    break;
       
  1052  
       
  1053  	case 32:
       
  1054 -	    nbytes = rep.nItems << 2;
       
  1055 -	    rbytes = rep.nItems * sizeof (long) + 1;
       
  1056 -	    if (rbytes > 0 &&
       
  1057 -		(*prop = (unsigned char *) Xmalloc ((unsigned)rbytes)))
       
  1058 -		_XRead32 (dpy, (long *) *prop, nbytes);
       
  1059 +	    if (rep.nItems < (INT_MAX / sizeof (long))) {
       
  1060 +		nbytes = rep.nItems << 2;
       
  1061 +		rbytes = rep.nItems * sizeof (long) + 1;
       
  1062 +		if ((*prop = Xmalloc (rbytes)))
       
  1063 +		    _XRead32 (dpy, (long *) *prop, nbytes);
       
  1064 +		else
       
  1065 +		    ret = BadAlloc;
       
  1066 +	    }
       
  1067  	    break;
       
  1068  
       
  1069  	default:
       
  1070 @@ -112,16 +127,13 @@ XGetDeviceProperty(Display* dpy, XDevice* dev,
       
  1071  	     * This part of the code should never be reached.  If it is,
       
  1072  	     * the server sent back a property with an invalid format.
       
  1073  	     */
       
  1074 -	    _XEatDataWords(dpy, rep.length);
       
  1075 -	    UnlockDisplay(dpy);
       
  1076 -	    SyncHandle();
       
  1077 -	    return(BadImplementation);
       
  1078 +	    ret = BadImplementation;
       
  1079  	}
       
  1080  	if (! *prop) {
       
  1081  	    _XEatDataWords(dpy, rep.length);
       
  1082 -	    UnlockDisplay(dpy);
       
  1083 -	    SyncHandle();
       
  1084 -	    return(BadAlloc);
       
  1085 +	    if (ret == Success)
       
  1086 +		ret = BadAlloc;
       
  1087 +	    goto out;
       
  1088  	}
       
  1089  	(*prop)[rbytes - 1] = '\0';
       
  1090      }
       
  1091 @@ -130,9 +142,10 @@ XGetDeviceProperty(Display* dpy, XDevice* dev,
       
  1092      *actual_format = rep.format;
       
  1093      *nitems = rep.nItems;
       
  1094      *bytes_after = rep.bytesAfter;
       
  1095 +  out:
       
  1096      UnlockDisplay (dpy);
       
  1097      SyncHandle ();
       
  1098  
       
  1099 -    return Success;
       
  1100 +    return ret;
       
  1101  }
       
  1102  
       
  1103 -- 
       
  1104 1.7.9.2
       
  1105 
       
  1106 From 03f9746651d8d67c6d449737bd1681eb394b094c Mon Sep 17 00:00:00 2001
       
  1107 From: Alan Coopersmith <[email protected]>
       
  1108 Date: Sun, 10 Mar 2013 00:22:14 -0800
       
  1109 Subject: [PATCH:libXi 12/13] Avoid integer overflow in XListInputDevices()
       
  1110  [CVE-2013-1984 8/8]
       
  1111 
       
  1112 If the length of the reply as reported by the Xserver is too long, it
       
  1113 could overflow the calculation for the size of the buffer to copy the
       
  1114 reply into, causing memory corruption.
       
  1115 
       
  1116 Signed-off-by: Alan Coopersmith <[email protected]>
       
  1117 Reviewed-by: Peter Hutterer <[email protected]>
       
  1118 ---
       
  1119  src/XListDev.c |   10 ++++++----
       
  1120  1 file changed, 6 insertions(+), 4 deletions(-)
       
  1121 
       
  1122 diff --git a/src/XListDev.c b/src/XListDev.c
       
  1123 index 1fa4747..1c14b96 100644
       
  1124 --- a/src/XListDev.c
       
  1125 +++ b/src/XListDev.c
       
  1126 @@ -60,6 +60,7 @@ SOFTWARE.
       
  1127  #include <X11/extensions/XInput.h>
       
  1128  #include <X11/extensions/extutil.h>
       
  1129  #include "XIint.h"
       
  1130 +#include <limits.h>
       
  1131  
       
  1132  /* Calculate length field to a multiples of sizeof(XID). XIDs are typedefs
       
  1133   * to ulong and thus may be 8 bytes on some platforms. This can trigger a
       
  1134 @@ -179,7 +180,7 @@ XListInputDevices(
       
  1135      XAnyClassPtr Any;
       
  1136      char *nptr, *Nptr;
       
  1137      int i;
       
  1138 -    long rlen;
       
  1139 +    unsigned long rlen;
       
  1140      XExtDisplayInfo *info = XInput_find_display(dpy);
       
  1141  
       
  1142      LockDisplay(dpy);
       
  1143 @@ -198,9 +199,10 @@ XListInputDevices(
       
  1144  
       
  1145      if ((*ndevices = rep.ndevices)) {	/* at least 1 input device */
       
  1146  	size = *ndevices * sizeof(XDeviceInfo);
       
  1147 -	rlen = rep.length << 2;	/* multiply length by 4    */
       
  1148 -	list = (xDeviceInfo *) Xmalloc(rlen);
       
  1149 -	slist = list;
       
  1150 +	if (rep.length < (INT_MAX >> 2)) {
       
  1151 +	    rlen = rep.length << 2;	/* multiply length by 4    */
       
  1152 +	    slist = list = Xmalloc(rlen);
       
  1153 +	}
       
  1154  	if (!slist) {
       
  1155  	    _XEatDataWords(dpy, rep.length);
       
  1156  	    UnlockDisplay(dpy);
       
  1157 -- 
       
  1158 1.7.9.2
       
  1159 
       
  1160 From 5019f7a8f06b6826cd197d8def6feb841f1490ec Mon Sep 17 00:00:00 2001
       
  1161 From: Alan Coopersmith <[email protected]>
       
  1162 Date: Sun, 10 Mar 2013 00:16:22 -0800
       
  1163 Subject: [PATCH:libXi 13/13] sign extension issue in XListInputDevices()
       
  1164  [CVE-2013-1995]
       
  1165 
       
  1166 nptr is (signed) char, which can be negative, and will sign extend
       
  1167 when added to the int size, which means size can be subtracted from,
       
  1168 leading to allocating too small a buffer to hold the data being copied
       
  1169 from the X server's reply.
       
  1170 
       
  1171 v2: check that string size fits inside the data read from the server,
       
  1172     so that we don't read out of bounds either
       
  1173 
       
  1174 Reported-by: Ilja Van Sprundel <[email protected]>
       
  1175 Signed-off-by: Alan Coopersmith <[email protected]>
       
  1176 Reviewed-by: Peter Hutterer <[email protected]>
       
  1177 ---
       
  1178  src/XListDev.c |   16 ++++++++++------
       
  1179  1 file changed, 10 insertions(+), 6 deletions(-)
       
  1180 
       
  1181 diff --git a/src/XListDev.c b/src/XListDev.c
       
  1182 index 1c14b96..b85ff3c 100644
       
  1183 --- a/src/XListDev.c
       
  1184 +++ b/src/XListDev.c
       
  1185 @@ -73,7 +73,7 @@ static int pad_to_xid(int base_size)
       
  1186      return ((base_size + padsize - 1)/padsize) * padsize;
       
  1187  }
       
  1188  
       
  1189 -static int
       
  1190 +static size_t
       
  1191  SizeClassInfo(xAnyClassPtr *any, int num_classes)
       
  1192  {
       
  1193      int size = 0;
       
  1194 @@ -170,7 +170,7 @@ XListInputDevices(
       
  1195      register Display	*dpy,
       
  1196      int			*ndevices)
       
  1197  {
       
  1198 -    int size;
       
  1199 +    size_t size;
       
  1200      xListInputDevicesReq *req;
       
  1201      xListInputDevicesReply rep;
       
  1202      xDeviceInfo *list, *slist = NULL;
       
  1203 @@ -178,7 +178,7 @@ XListInputDevices(
       
  1204      XDeviceInfo *clist = NULL;
       
  1205      xAnyClassPtr any, sav_any;
       
  1206      XAnyClassPtr Any;
       
  1207 -    char *nptr, *Nptr;
       
  1208 +    unsigned char *nptr, *Nptr;
       
  1209      int i;
       
  1210      unsigned long rlen;
       
  1211      XExtDisplayInfo *info = XInput_find_display(dpy);
       
  1212 @@ -217,9 +217,12 @@ XListInputDevices(
       
  1213              size += SizeClassInfo(&any, (int)list->num_classes);
       
  1214  	}
       
  1215  
       
  1216 -	for (i = 0, nptr = (char *)any; i < *ndevices; i++) {
       
  1217 +	Nptr = ((unsigned char *)list) + rlen + 1;
       
  1218 +	for (i = 0, nptr = (unsigned char *)any; i < *ndevices; i++) {
       
  1219  	    size += *nptr + 1;
       
  1220  	    nptr += (*nptr + 1);
       
  1221 +	    if (nptr > Nptr)
       
  1222 +		goto out;
       
  1223  	}
       
  1224  
       
  1225  	clist = (XDeviceInfoPtr) Xmalloc(size);
       
  1226 @@ -245,8 +248,8 @@ XListInputDevices(
       
  1227  	}
       
  1228  
       
  1229  	clist = sclist;
       
  1230 -	nptr = (char *)any;
       
  1231 -	Nptr = (char *)Any;
       
  1232 +	nptr = (unsigned char *)any;
       
  1233 +	Nptr = (unsigned char *)Any;
       
  1234  	for (i = 0; i < *ndevices; i++, clist++) {
       
  1235  	    clist->name = (char *)Nptr;
       
  1236  	    memcpy(Nptr, nptr + 1, *nptr);
       
  1237 @@ -256,6 +259,7 @@ XListInputDevices(
       
  1238  	}
       
  1239      }
       
  1240  
       
  1241 +  out:
       
  1242      XFree((char *)slist);
       
  1243      UnlockDisplay(dpy);
       
  1244      SyncHandle();
       
  1245 -- 
       
  1246 1.7.9.2
       
  1247