summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlan Coopersmith <alan.coopersmith@oracle.com>2013-03-10 13:30:55 -0700
committerAlan Coopersmith <alan.coopersmith@oracle.com>2013-05-23 08:13:26 -0700
commit17071c1c608247800b2ca03a35b1fcc9c4cabe6c (patch)
treec87ff8e4a349da759782bb4e0ad05656d2b30d5c /src
parent528419b9ef437e7eeafb41bf45e8ff7d818bd845 (diff)
Avoid integer overflow in XGetDeviceProperties() [CVE-2013-1984 7/8]
If the number of items as reported by the Xserver is too large, it could overflow the calculation for the size of the buffer to copy the reply into, causing memory corruption. Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Diffstat (limited to 'src')
-rw-r--r--src/XGetDProp.c61
1 files changed, 37 insertions, 24 deletions
diff --git a/src/XGetDProp.c b/src/XGetDProp.c
index f9e8f0c..3691122 100644
--- a/src/XGetDProp.c
+++ b/src/XGetDProp.c
@@ -38,6 +38,7 @@ in this Software without prior written authorization from the author.
#include <X11/extensions/XInput.h>
#include <X11/extensions/extutil.h>
#include "XIint.h"
+#include <limits.h>
int
XGetDeviceProperty(Display* dpy, XDevice* dev,
@@ -48,7 +49,8 @@ XGetDeviceProperty(Display* dpy, XDevice* dev,
{
xGetDevicePropertyReq *req;
xGetDevicePropertyReply rep;
- long nbytes, rbytes;
+ unsigned long nbytes, rbytes;
+ int ret = Success;
XExtDisplayInfo *info = XInput_find_display(dpy);
@@ -81,30 +83,43 @@ XGetDeviceProperty(Display* dpy, XDevice* dev,
* data, but this last byte is null terminated and convenient for
* returning string properties, so the client doesn't then have to
* recopy the string to make it null terminated.
+ *
+ * Maximum item limits are set to both prevent integer overflow when
+ * calculating the amount of memory to malloc, and to limit how much
+ * memory will be used if a server provides an insanely high count.
*/
switch (rep.format) {
case 8:
- nbytes = rep.nItems;
- rbytes = rep.nItems + 1;
- if (rbytes > 0 &&
- (*prop = (unsigned char *) Xmalloc ((unsigned)rbytes)))
- _XReadPad (dpy, (char *) *prop, nbytes);
+ if (rep.nItems < INT_MAX) {
+ nbytes = rep.nItems;
+ rbytes = rep.nItems + 1;
+ if ((*prop = Xmalloc (rbytes)))
+ _XReadPad (dpy, (char *) *prop, nbytes);
+ else
+ ret = BadAlloc;
+ }
break;
case 16:
- nbytes = rep.nItems << 1;
- rbytes = rep.nItems * sizeof (short) + 1;
- if (rbytes > 0 &&
- (*prop = (unsigned char *) Xmalloc ((unsigned)rbytes)))
- _XRead16Pad (dpy, (short *) *prop, nbytes);
+ if (rep.nItems < (INT_MAX / sizeof (short))) {
+ nbytes = rep.nItems << 1;
+ rbytes = rep.nItems * sizeof (short) + 1;
+ if ((*prop = Xmalloc (rbytes)))
+ _XRead16Pad (dpy, (short *) *prop, nbytes);
+ else
+ ret = BadAlloc;
+ }
break;
case 32:
- nbytes = rep.nItems << 2;
- rbytes = rep.nItems * sizeof (long) + 1;
- if (rbytes > 0 &&
- (*prop = (unsigned char *) Xmalloc ((unsigned)rbytes)))
- _XRead32 (dpy, (long *) *prop, nbytes);
+ if (rep.nItems < (INT_MAX / sizeof (long))) {
+ nbytes = rep.nItems << 2;
+ rbytes = rep.nItems * sizeof (long) + 1;
+ if ((*prop = Xmalloc (rbytes)))
+ _XRead32 (dpy, (long *) *prop, nbytes);
+ else
+ ret = BadAlloc;
+ }
break;
default:
@@ -112,16 +127,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.
*/
- _XEatDataWords(dpy, rep.length);
- UnlockDisplay(dpy);
- SyncHandle();
- return(BadImplementation);
+ ret = BadImplementation;
}
if (! *prop) {
_XEatDataWords(dpy, rep.length);
- UnlockDisplay(dpy);
- SyncHandle();
- return(BadAlloc);
+ if (ret == Success)
+ ret = BadAlloc;
+ goto out;
}
(*prop)[rbytes - 1] = '\0';
}
@@ -130,9 +142,10 @@ XGetDeviceProperty(Display* dpy, XDevice* dev,
*actual_format = rep.format;
*nitems = rep.nItems;
*bytes_after = rep.bytesAfter;
+ out:
UnlockDisplay (dpy);
SyncHandle ();
- return Success;
+ return ret;
}