From 28a91c1944be8c8e8185eac5d75095ebd39339a6 Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Sun, 10 Mar 2013 00:16:22 -0800 Subject: [PATCH 15/16] sign extension issue in XListInputDevices() [CVE-2013-1995] nptr is (signed) char, which can be negative, and will sign extend when added to the int size, which means size can be subtracted from, leading to allocating too small a buffer to hold the data being copied from the X server's reply. v2: check that string size fits inside the data read from the server, so that we don't read out of bounds either Reported-by: Ilja Van Sprundel Signed-off-by: Alan Coopersmith Reviewed-by: Peter Hutterer (cherry picked from commit 81b4df8ac6aa1520c41c3526961014a6f115cc46) (cherry picked from commit 62c1e47de0448242a0dd1f5226be93f92a06824f) Conflicts: src/XListDev.c --- src/XListDev.c | 16 ++++++++++------ 1 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/XListDev.c b/src/XListDev.c index d8abddb..7f4538c 100644 --- a/src/XListDev.c +++ b/src/XListDev.c @@ -59,7 +59,7 @@ SOFTWARE. #include "XIint.h" #include -static int +static size_t SizeClassInfo(xAnyClassPtr *any, int num_classes) { int size = 0; @@ -155,7 +155,7 @@ XListInputDevices( register Display *dpy, int *ndevices) { - int size; + size_t size; xListInputDevicesReq *req; xListInputDevicesReply rep; xDeviceInfo *list, *slist = NULL; @@ -163,7 +163,7 @@ XListInputDevices( XDeviceInfo *clist = NULL; xAnyClassPtr any, sav_any; XAnyClassPtr Any; - char *nptr, *Nptr; + unsigned char *nptr, *Nptr; int i; unsigned long rlen; XExtDisplayInfo *info = XInput_find_display(dpy); @@ -202,9 +202,12 @@ XListInputDevices( size += SizeClassInfo(&any, (int)list->num_classes); } - for (i = 0, nptr = (char *)any; i < *ndevices; i++) { + Nptr = ((unsigned char *)list) + rlen + 1; + for (i = 0, nptr = (unsigned char *)any; i < *ndevices; i++) { size += *nptr + 1; nptr += (*nptr + 1); + if (nptr > Nptr) + goto out; } clist = (XDeviceInfoPtr) Xmalloc(size); @@ -230,8 +233,8 @@ XListInputDevices( } clist = sclist; - nptr = (char *)any; - Nptr = (char *)Any; + nptr = (unsigned char *)any; + Nptr = (unsigned char *)Any; for (i = 0; i < *ndevices; i++, clist++) { clist->name = (char *)Nptr; memcpy(Nptr, nptr + 1, *nptr); @@ -241,6 +244,7 @@ XListInputDevices( } } + out: XFree((char *)slist); UnlockDisplay(dpy); SyncHandle(); -- 1.7.7.1