From eb0cf9b0ba0ad213954a15c757932b8005bff99e Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Wed, 1 May 2013 23:58:39 -0700 Subject: [PATCH 3/3] Use _XEatDataWords to avoid overflow of rep.length bit shifting rep.length is a CARD32, so rep.length << 2 could overflow in 32-bit builds Signed-off-by: Alan Coopersmith Reviewed-by: Peter Hutterer (cherry picked from commit 59b8e1388a687f871831ac5a9e0ac11de75e2516) (cherry picked from commit 4579fadd11883c62db486ecc64c40342c2ab5506) --- configure.ac | 6 ++++++ src/XGMotion.c | 2 +- src/XGetDCtl.c | 2 +- src/XGetDProp.c | 5 ++--- src/XGetFCtl.c | 2 +- src/XGetKMap.c | 2 +- src/XGetMMap.c | 2 +- src/XGetProp.c | 4 +--- src/XGtSelect.c | 2 +- src/XIProperties.c | 7 +++---- src/XIint.h | 19 +++++++++++++++++++ src/XListDProp.c | 2 +- src/XListDev.c | 2 +- src/XOpenDev.c | 2 +- src/XQueryDv.c | 2 +- 15 files changed, 41 insertions(+), 20 deletions(-) diff --git a/configure.ac b/configure.ac index 9d5d5eb..3ffdef3 100644 --- a/configure.ac +++ b/configure.ac @@ -28,6 +28,12 @@ XORG_CHECK_MALLOC_ZERO # Obtain compiler/linker options for depedencies PKG_CHECK_MODULES(XI, [xproto >= 7.0.13] [x11 >= 1.2.99.1] [xextproto >= 7.0.3] [xext >= 1.0.99.1] [inputproto >= 1.9.99.902]) +# Check for _XEatDataWords function that may be patched into older Xlib releases +SAVE_LIBS="$LIBS" +LIBS="$XI_LIBS" +AC_CHECK_FUNCS([_XEatDataWords]) +LIBS="$SAVE_LIBS" + # Check for xmlto and asciidoc for man page conversion # (only needed by people building tarballs) if test "$have_xmlto" = yes && test "$have_asciidoc" = yes; then diff --git a/src/XGMotion.c b/src/XGMotion.c index aee6671..f3b6751 100644 --- a/src/XGMotion.c +++ b/src/XGMotion.c @@ -109,7 +109,7 @@ XGetDeviceMotionEvents( Xfree(bufp); Xfree(savp); *nEvents = 0; - _XEatData(dpy, (unsigned long)size); + _XEatDataWords(dpy, rep.length); UnlockDisplay(dpy); SyncHandle(); return (NULL); diff --git a/src/XGetDCtl.c b/src/XGetDCtl.c index 729b0a0..a1e49ee 100644 --- a/src/XGetDCtl.c +++ b/src/XGetDCtl.c @@ -91,7 +91,7 @@ XGetDeviceControl( nbytes = (long)rep.length << 2; d = (xDeviceState *) Xmalloc((unsigned)nbytes); if (!d) { - _XEatData(dpy, (unsigned long)nbytes); + _XEatDataWords(dpy, rep.length); goto out; } sav = d; diff --git a/src/XGetDProp.c b/src/XGetDProp.c index 5d44f91..f9e8f0c 100644 --- a/src/XGetDProp.c +++ b/src/XGetDProp.c @@ -112,14 +112,13 @@ XGetDeviceProperty(Display* dpy, XDevice* dev, * This part of the code should never be reached. If it is, * the server sent back a property with an invalid format. */ - nbytes = rep.length << 2; - _XEatData(dpy, (unsigned long) nbytes); + _XEatDataWords(dpy, rep.length); UnlockDisplay(dpy); SyncHandle(); return(BadImplementation); } if (! *prop) { - _XEatData(dpy, (unsigned long) nbytes); + _XEatDataWords(dpy, rep.length); UnlockDisplay(dpy); SyncHandle(); return(BadAlloc); diff --git a/src/XGetFCtl.c b/src/XGetFCtl.c index 3d64404..5a05397 100644 --- a/src/XGetFCtl.c +++ b/src/XGetFCtl.c @@ -91,7 +91,7 @@ XGetFeedbackControl( nbytes = (long)rep.length << 2; f = (xFeedbackState *) Xmalloc((unsigned)nbytes); if (!f) { - _XEatData(dpy, (unsigned long)nbytes); + _XEatDataWords(dpy, rep.length); goto out; } sav = f; diff --git a/src/XGetKMap.c b/src/XGetKMap.c index 4596ff0..0f1d077 100644 --- a/src/XGetKMap.c +++ b/src/XGetKMap.c @@ -95,7 +95,7 @@ XGetDeviceKeyMapping(register Display * dpy, XDevice * dev, if (mapping) _XRead(dpy, (char *)mapping, nbytes); else - _XEatData(dpy, (unsigned long)nbytes); + _XEatDataWords(dpy, rep.length); } UnlockDisplay(dpy); diff --git a/src/XGetMMap.c b/src/XGetMMap.c index a4bf094..a9b5950 100644 --- a/src/XGetMMap.c +++ b/src/XGetMMap.c @@ -89,7 +89,7 @@ XGetDeviceModifierMapping( if (res->modifiermap) _XReadPad(dpy, (char *)res->modifiermap, nbytes); else - _XEatData(dpy, (unsigned long)nbytes); + _XEatDataWords(dpy, rep.length); res->max_keypermod = rep.numKeyPerModifier; } diff --git a/src/XGetProp.c b/src/XGetProp.c index 7ccf9fe..ca6f657 100644 --- a/src/XGetProp.c +++ b/src/XGetProp.c @@ -65,7 +65,6 @@ XGetDeviceDontPropagateList( int *count) { XEventClass *list = NULL; - int rlen; xGetDeviceDontPropagateListReq *req; xGetDeviceDontPropagateListReply rep; XExtDisplayInfo *info = XInput_find_display(dpy); @@ -87,7 +86,6 @@ XGetDeviceDontPropagateList( *count = rep.count; if (*count) { - rlen = rep.length << 2; list = (XEventClass *) Xmalloc(rep.length * sizeof(XEventClass)); if (list) { int i; @@ -102,7 +100,7 @@ XGetDeviceDontPropagateList( list[i] = (XEventClass) ec; } } else - _XEatData(dpy, (unsigned long)rlen); + _XEatDataWords(dpy, rep.length); } UnlockDisplay(dpy); diff --git a/src/XGtSelect.c b/src/XGtSelect.c index dea8c4c..495e40b 100644 --- a/src/XGtSelect.c +++ b/src/XGtSelect.c @@ -101,7 +101,7 @@ XGetSelectedExtensionEvents( (XEventClass *) Xmalloc(*this_client_count * sizeof(XEventClass)); if (!*this_client_list) { - _XEatData(dpy, (unsigned long)tlen + alen); + _XEatDataWords(dpy, rep.length); UnlockDisplay(dpy); SyncHandle(); return (Success); diff --git a/src/XIProperties.c b/src/XIProperties.c index 83a7a68..5e58fb6 100644 --- a/src/XIProperties.c +++ b/src/XIProperties.c @@ -64,7 +64,7 @@ XIListProperties(Display* dpy, int deviceid, int *num_props_return) props = (Atom*)Xmalloc(rep.num_properties * sizeof(Atom)); if (!props) { - _XEatData(dpy, rep.num_properties << 2); + _XEatDataWords(dpy, rep.length); goto cleanup; } @@ -203,8 +203,7 @@ XIGetProperty(Display* dpy, int deviceid, Atom property, long offset, * This part of the code should never be reached. If it is, * the server sent back a property with an invalid format. */ - nbytes = rep.length << 2; - _XEatData(dpy, nbytes); + _XEatDataWords(dpy, rep.length); UnlockDisplay(dpy); SyncHandle(); return(BadImplementation); @@ -222,7 +221,7 @@ XIGetProperty(Display* dpy, int deviceid, Atom property, long offset, *data = Xmalloc(rbytes); if (!(*data)) { - _XEatData(dpy, nbytes); + _XEatDataWords(dpy, rep.length); UnlockDisplay(dpy); SyncHandle(); return(BadAlloc); diff --git a/src/XIint.h b/src/XIint.h index b27f04a..5de4913 100644 --- a/src/XIint.h +++ b/src/XIint.h @@ -5,7 +5,12 @@ #ifndef _XIINT_H_ #define _XIINT_H_ +#ifdef HAVE_CONFIG_H +#include +#endif + #include +#include extern XExtDisplayInfo *XInput_find_display(Display *); @@ -65,4 +70,18 @@ next_block(void **ptr, int size) { return ret; } +#ifndef HAVE__XEATDATAWORDS +#include /* for LONG64 on 64-bit platforms */ +#include + +static inline void _XEatDataWords(Display *dpy, unsigned long n) +{ +# ifndef LONG64 + if (n >= (ULONG_MAX >> 2)) + _XIOError(dpy); +# endif + _XEatData (dpy, n << 2); +} +#endif + #endif diff --git a/src/XListDProp.c b/src/XListDProp.c index 66b9eca..a87164d 100644 --- a/src/XListDProp.c +++ b/src/XListDProp.c @@ -65,7 +65,7 @@ XListDeviceProperties(Display* dpy, XDevice* dev, int *nprops_return) props = (Atom*)Xmalloc(rep.nAtoms * sizeof(Atom)); if (!props) { - _XEatData(dpy, rep.nAtoms << 2); + _XEatDataWords(dpy, rep.length); goto cleanup; } diff --git a/src/XListDev.c b/src/XListDev.c index c544ae0..ad8f548 100644 --- a/src/XListDev.c +++ b/src/XListDev.c @@ -187,7 +187,7 @@ XListInputDevices( list = (xDeviceInfo *) Xmalloc(rlen); slist = list; if (!slist) { - _XEatData(dpy, (unsigned long)rlen); + _XEatDataWords(dpy, rep.length); UnlockDisplay(dpy); SyncHandle(); return (XDeviceInfo *) NULL; diff --git a/src/XOpenDev.c b/src/XOpenDev.c index b50d5b0..e09ccbd 100644 --- a/src/XOpenDev.c +++ b/src/XOpenDev.c @@ -98,7 +98,7 @@ XOpenDevice( if (rlen - dlen > 0) _XEatData(dpy, (unsigned long)rlen - dlen); } else - _XEatData(dpy, (unsigned long)rlen); + _XEatDataWords(dpy, rep.length); UnlockDisplay(dpy); SyncHandle(); diff --git a/src/XQueryDv.c b/src/XQueryDv.c index 637d5cf..9ef0190 100644 --- a/src/XQueryDv.c +++ b/src/XQueryDv.c @@ -88,7 +88,7 @@ XQueryDeviceState( if (rlen > 0) { data = Xmalloc(rlen); if (!data) { - _XEatData(dpy, (unsigned long)rlen); + _XEatDataWords(dpy, rep.length); goto out; } _XRead(dpy, data, rlen); -- 1.7.7.1