Commit 748af521 authored by Alan Coopersmith's avatar Alan Coopersmith Committed by Ulrich Sibiller

integer overflow in XGetPointerMapping() & XGetKeyboardMapping() [CVE-2013-1981 12/13]

Ensure that we don't underallocate when the server claims a very large reply Signed-off-by: 's avatarAlan Coopersmith <alan.coopersmith@oracle.com> Reviewed-by: 's avatarMatthieu Herrb <matthieu.herrb@laas.fr> Signed-off-by: 's avatarJulien Cristau <jcristau@debian.org> Backported-to-NX-by: 's avatarUlrich Sibiller <uli42@gmx.de>
parent 9501bce2
...@@ -29,6 +29,7 @@ in this Software without prior written authorization from The Open Group. ...@@ -29,6 +29,7 @@ in this Software without prior written authorization from The Open Group.
#include <config.h> #include <config.h>
#endif #endif
#include "Xlibint.h" #include "Xlibint.h"
#include <limits.h>
#ifdef MIN /* some systems define this in <sys/param.h> */ #ifdef MIN /* some systems define this in <sys/param.h> */
#undef MIN #undef MIN
...@@ -42,7 +43,7 @@ int XGetPointerMapping ( ...@@ -42,7 +43,7 @@ int XGetPointerMapping (
{ {
unsigned char mapping[256]; /* known fixed size */ unsigned char mapping[256]; /* known fixed size */
long nbytes, remainder = 0; unsigned long nbytes, remainder = 0;
xGetPointerMappingReply rep; xGetPointerMappingReply rep;
register xReq *req; register xReq *req;
...@@ -54,9 +55,15 @@ int XGetPointerMapping ( ...@@ -54,9 +55,15 @@ int XGetPointerMapping (
return 0; return 0;
} }
nbytes = (long)rep.length << 2;
/* Don't count on the server returning a valid value */ /* Don't count on the server returning a valid value */
if (rep.length >= (INT_MAX >> 2)) {
_XEatDataWords(dpy, rep.length);
UnlockDisplay(dpy);
SyncHandle();
return 0;
}
nbytes = (unsigned long) rep.length << 2;
if (nbytes > sizeof mapping) { if (nbytes > sizeof mapping) {
remainder = nbytes - sizeof mapping; remainder = nbytes - sizeof mapping;
nbytes = sizeof mapping; nbytes = sizeof mapping;
...@@ -69,7 +76,7 @@ int XGetPointerMapping ( ...@@ -69,7 +76,7 @@ int XGetPointerMapping (
} }
if (remainder) if (remainder)
_XEatData(dpy, (unsigned long)remainder); _XEatData(dpy, remainder);
UnlockDisplay(dpy); UnlockDisplay(dpy);
SyncHandle(); SyncHandle();
...@@ -86,8 +93,8 @@ XGetKeyboardMapping (Display *dpy, ...@@ -86,8 +93,8 @@ XGetKeyboardMapping (Display *dpy,
int count, int count,
int *keysyms_per_keycode) int *keysyms_per_keycode)
{ {
long nbytes; unsigned long nbytes;
unsigned long nkeysyms; CARD32 nkeysyms;
register KeySym *mapping = NULL; register KeySym *mapping = NULL;
xGetKeyboardMappingReply rep; xGetKeyboardMappingReply rep;
register xGetKeyboardMappingReq *req; register xGetKeyboardMappingReq *req;
...@@ -102,17 +109,19 @@ XGetKeyboardMapping (Display *dpy, ...@@ -102,17 +109,19 @@ XGetKeyboardMapping (Display *dpy,
return (KeySym *) NULL; return (KeySym *) NULL;
} }
nkeysyms = (unsigned long) rep.length; nkeysyms = rep.length;
if (nkeysyms > 0) { if (nkeysyms > 0) {
if (nkeysyms < (INT_MAX / sizeof (KeySym))) {
nbytes = nkeysyms * sizeof (KeySym); nbytes = nkeysyms * sizeof (KeySym);
mapping = (KeySym *) Xmalloc ((unsigned) nbytes); mapping = Xmalloc (nbytes);
nbytes = nkeysyms << 2; }
if (! mapping) { if (! mapping) {
_XEatData(dpy, (unsigned long) nbytes); _XEatDataWords(dpy, rep.length);
UnlockDisplay(dpy); UnlockDisplay(dpy);
SyncHandle(); SyncHandle();
return (KeySym *) NULL; return (KeySym *) NULL;
} }
nbytes = nkeysyms << 2;
_XRead32 (dpy, (long *) mapping, nbytes); _XRead32 (dpy, (long *) mapping, nbytes);
} }
*keysyms_per_keycode = rep.keySymsPerKeyCode; *keysyms_per_keycode = rep.keySymsPerKeyCode;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment