From 1f6a3dbf699b85c0ea715ef21de7e7095a714e12 Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Fri, 1 Mar 2013 22:49:01 -0800 Subject: integer overflow in XGetMotionEvents() [CVE-2013-1981 4/13] If the reported number of motion events is too large, the calculations to allocate memory for them may overflow, leaving us writing beyond the bounds of the allocation. v2: Ensure nEvents is set to 0 when returning NULL events pointer Reported-by: Ilja Van Sprundel Signed-off-by: Alan Coopersmith --- src/GetMoEv.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/GetMoEv.c b/src/GetMoEv.c index 3db176fe..ad9c7727 100644 --- a/src/GetMoEv.c +++ b/src/GetMoEv.c @@ -28,6 +28,7 @@ in this Software without prior written authorization from The Open Group. #include #endif #include "Xlibint.h" +#include XTimeCoord *XGetMotionEvents( register Display *dpy, @@ -39,7 +40,6 @@ XTimeCoord *XGetMotionEvents( xGetMotionEventsReply rep; register xGetMotionEventsReq *req; XTimeCoord *tc = NULL; - long nbytes; LockDisplay(dpy); GetReq(GetMotionEvents, req); req->window = w; @@ -52,26 +52,22 @@ XTimeCoord *XGetMotionEvents( return (NULL); } - if (rep.nEvents) { - if (! (tc = (XTimeCoord *) - Xmalloc( (unsigned) - (nbytes = (long) rep.nEvents * sizeof(XTimeCoord))))) { - _XEatData (dpy, (unsigned long) nbytes); - UnlockDisplay(dpy); - SyncHandle(); - return (NULL); - } + if (rep.nEvents && (rep.nEvents < (INT_MAX / sizeof(XTimeCoord)))) + tc = Xmalloc(rep.nEvents * sizeof(XTimeCoord)); + if (tc == NULL) { + /* server returned either no events or a bad event count */ + *nEvents = 0; + _XEatDataWords (dpy, rep.length); } - - *nEvents = rep.nEvents; - nbytes = SIZEOF (xTimecoord); + else { register XTimeCoord *tcptr; - register int i; + unsigned int i; xTimecoord xtc; + *nEvents = (int) rep.nEvents; for (i = rep.nEvents, tcptr = tc; i > 0; i--, tcptr++) { - _XRead (dpy, (char *) &xtc, nbytes); + _XRead (dpy, (char *) &xtc, SIZEOF (xTimecoord)); tcptr->time = xtc.time; tcptr->x = cvtINT16toShort (xtc.x); tcptr->y = cvtINT16toShort (xtc.y); -- cgit v1.2.3