diff -r 800e8c2d47f1 -r d5dacbb8de2b open-src/lib/libX11/CVE-2013-1997.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/open-src/lib/libX11/CVE-2013-1997.patch Wed May 15 13:44:02 2013 -0700 @@ -0,0 +1,789 @@ +From b68b8dcddbb517cee2fe370ffd3bacae99c75299 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Fri, 1 Mar 2013 19:30:09 -0800 +Subject: [PATCH:libX11 08/38] unvalidated lengths in XAllocColorCells() + [CVE-2013-1997 1/15] + +If a broken server returned larger than requested values for nPixels or +nMasks, XAllocColorCells would happily overflow the buffers provided by +the caller to write the results into. + +Reported-by: Ilja Van Sprundel +Signed-off-by: Alan Coopersmith +Reviewed-by: Matthieu Herrb +--- + src/AllCells.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/src/AllCells.c b/src/AllCells.c +index ddd9c22..6e97e11 100644 +--- a/src/AllCells.c ++++ b/src/AllCells.c +@@ -53,8 +53,13 @@ Status XAllocColorCells( + status = _XReply(dpy, (xReply *)&rep, 0, xFalse); + + if (status) { +- _XRead32 (dpy, (long *) pixels, 4L * (long) (rep.nPixels)); +- _XRead32 (dpy, (long *) masks, 4L * (long) (rep.nMasks)); ++ if ((rep.nPixels > ncolors) || (rep.nMasks > nplanes)) { ++ _XEatDataWords(dpy, rep.length); ++ status = 0; /* Failure */ ++ } else { ++ _XRead32 (dpy, (long *) pixels, 4L * (long) (rep.nPixels)); ++ _XRead32 (dpy, (long *) masks, 4L * (long) (rep.nMasks)); ++ } + } + + UnlockDisplay(dpy); +-- +1.7.9.2 + +From 638d668a99734cf68bea1b799aece5706fb18b08 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Fri, 1 Mar 2013 22:49:01 -0800 +Subject: [PATCH:libX11 09/38] unvalidated index in + _XkbReadGetDeviceInfoReply() [CVE-2013-1997 + 2/15] + +If the X server returns more buttons than are allocated in the XKB +device info structures, out of bounds writes could occur. + +Reported-by: Ilja Van Sprundel +Signed-off-by: Alan Coopersmith +Reviewed-by: Matthieu Herrb +--- + src/xkb/XKBExtDev.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/xkb/XKBExtDev.c b/src/xkb/XKBExtDev.c +index 353e769..dd383bc 100644 +--- a/src/xkb/XKBExtDev.c ++++ b/src/xkb/XKBExtDev.c +@@ -181,6 +181,9 @@ int tmp; + return tmp; + } + if (rep->nBtnsWanted>0) { ++ if (((unsigned short) rep->firstBtnWanted + rep->nBtnsWanted) ++ >= devi->num_btns) ++ goto BAILOUT; + act= &devi->btn_acts[rep->firstBtnWanted]; + bzero((char *)act,(rep->nBtnsWanted*sizeof(XkbAction))); + } +@@ -190,6 +193,9 @@ int tmp; + goto BAILOUT; + if (rep->nBtnsRtrn>0) { + int size; ++ if (((unsigned short) rep->firstBtnRtrn + rep->nBtnsRtrn) ++ >= devi->num_btns) ++ goto BAILOUT; + act= &devi->btn_acts[rep->firstBtnRtrn]; + size= rep->nBtnsRtrn*SIZEOF(xkbActionWireDesc); + if (!_XkbCopyFromReadBuffer(&buf,(char *)act,size)) +-- +1.7.9.2 + +From 1807e71a8a30aa2cff099708c508a25a9b6ba9da Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sat, 2 Mar 2013 09:12:47 -0800 +Subject: [PATCH:libX11 10/38] unvalidated indexes in _XkbReadGeomShapes() + [CVE-2013-1997 3/15] + +If the X server returns shape indexes outside the range of the number +of shapes it told us to allocate, out of bounds memory access could occur. + +Reported-by: Ilja Van Sprundel +Signed-off-by: Alan Coopersmith +Reviewed-by: Matthieu Herrb +--- + src/xkb/XKBGeom.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/src/xkb/XKBGeom.c b/src/xkb/XKBGeom.c +index 7594a3d..4ad21f8 100644 +--- a/src/xkb/XKBGeom.c ++++ b/src/xkb/XKBGeom.c +@@ -364,12 +364,16 @@ Status rtrn; + } + ol->num_points= olWire->nPoints; + } +- if (shapeWire->primaryNdx!=XkbNoShape) ++ if ((shapeWire->primaryNdx!=XkbNoShape) && ++ (shapeWire->primaryNdx < shapeWire->nOutlines)) + shape->primary= &shape->outlines[shapeWire->primaryNdx]; +- else shape->primary= NULL; +- if (shapeWire->approxNdx!=XkbNoShape) ++ else ++ shape->primary= NULL; ++ if ((shapeWire->approxNdx!=XkbNoShape) && ++ (shapeWire->approxNdx < shapeWire->nOutlines)) + shape->approx= &shape->outlines[shapeWire->approxNdx]; +- else shape->approx= NULL; ++ else ++ shape->approx= NULL; + XkbComputeShapeBounds(shape); + } + return Success; +-- +1.7.9.2 + +From 8215ec8bcad57c9707353626d782ff66ebe13b06 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sat, 2 Mar 2013 09:18:26 -0800 +Subject: [PATCH:libX11 11/38] unvalidated indexes in + _XkbReadGetGeometryReply() [CVE-2013-1997 + 4/15] + +If the X server returns color indexes outside the range of the number of +colors it told us to allocate, out of bounds memory access could occur. + +Reported-by: Ilja Van Sprundel +Signed-off-by: Alan Coopersmith +Reviewed-by: Matthieu Herrb +--- + src/xkb/XKBGeom.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/xkb/XKBGeom.c b/src/xkb/XKBGeom.c +index 4ad21f8..7140a72 100644 +--- a/src/xkb/XKBGeom.c ++++ b/src/xkb/XKBGeom.c +@@ -619,6 +619,9 @@ XkbGeometryPtr geom; + if (status==Success) + status= _XkbReadGeomKeyAliases(&buf,geom,rep); + left= _XkbFreeReadBuffer(&buf); ++ if ((rep->baseColorNdx > geom->num_colors) || ++ (rep->labelColorNdx > geom->num_colors)) ++ status = BadLength; + if ((status!=Success) || left || buf.error) { + if (status==Success) + status= BadLength; +-- +1.7.9.2 + +From 77009b1f37ec583ef5ff17834c8a5cf2413f9ba6 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sat, 2 Mar 2013 09:28:33 -0800 +Subject: [PATCH:libX11 12/38] unvalidated index in _XkbReadKeySyms() + [CVE-2013-1997 5/15] + +If the X server returns keymap indexes outside the range of the number of +keys it told us to allocate, out of bounds memory access could occur. + +Reported-by: Ilja Van Sprundel +Signed-off-by: Alan Coopersmith +Reviewed-by: Matthieu Herrb +--- + src/xkb/XKBGetMap.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/xkb/XKBGetMap.c b/src/xkb/XKBGetMap.c +index 30fb629..4a428d3 100644 +--- a/src/xkb/XKBGetMap.c ++++ b/src/xkb/XKBGetMap.c +@@ -151,9 +151,12 @@ XkbClientMapPtr map; + map= xkb->map; + if (map->key_sym_map==NULL) { + register int offset; ++ int size = xkb->max_key_code + 1; + XkbSymMapPtr oldMap; + xkbSymMapWireDesc *newMap; +- map->key_sym_map= _XkbTypedCalloc((xkb->max_key_code+1),XkbSymMapRec); ++ if (((unsigned short)rep->firstKeySym + rep->nKeySyms) > size) ++ return BadLength; ++ map->key_sym_map= _XkbTypedCalloc(size,XkbSymMapRec); + if (map->key_sym_map==NULL) + return BadAlloc; + if (map->syms==NULL) { +@@ -209,6 +212,8 @@ XkbClientMapPtr map; + KeySym * newSyms; + int tmp; + ++ if (((unsigned short)rep->firstKeySym + rep->nKeySyms) > map->num_syms) ++ return BadLength; + oldMap = &map->key_sym_map[rep->firstKeySym]; + for (i=0;i<(int)rep->nKeySyms;i++,oldMap++) { + newMap= (xkbSymMapWireDesc *) +-- +1.7.9.2 + +From ffc188aa4cbc0b0d0c612b62e45c29d485f86402 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sat, 2 Mar 2013 09:40:22 -0800 +Subject: [PATCH:libX11 13/38] unvalidated index in _XkbReadKeyActions() + [CVE-2013-1997 6/15] + +If the X server returns key action indexes outside the range of the number +of keys it told us to allocate, out of bounds memory access could occur. + +Reported-by: Ilja Van Sprundel +Signed-off-by: Alan Coopersmith +Reviewed-by: Matthieu Herrb +--- + src/xkb/XKBGetMap.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/xkb/XKBGetMap.c b/src/xkb/XKBGetMap.c +index 4a428d3..86ecf9d 100644 +--- a/src/xkb/XKBGetMap.c ++++ b/src/xkb/XKBGetMap.c +@@ -269,6 +269,10 @@ Status ret = Success; + symMap = &info->map->key_sym_map[rep->firstKeyAct]; + for (i=0;i<(int)rep->nKeyActs;i++,symMap++) { + if (numDesc[i]==0) { ++ if ((i + rep->firstKeyAct) > (info->max_key_code + 1)) { ++ ret = BadLength; ++ goto done; ++ } + info->server->key_acts[i+rep->firstKeyAct]= 0; + } + else { +-- +1.7.9.2 + +From 9f3d45b62875e7861deeecf849f90520395ee655 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sat, 2 Mar 2013 10:39:21 -0800 +Subject: [PATCH:libX11 14/38] unvalidated index in _XkbReadKeyBehaviors() + [CVE-2013-1997 7/15] + +If the X server returns key behavior indexes outside the range of the number +of keys it told us to allocate, out of bounds memory writes could occur. + +Reported-by: Ilja Van Sprundel +Signed-off-by: Alan Coopersmith +Reviewed-by: Matthieu Herrb +--- + src/xkb/XKBGetMap.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/xkb/XKBGetMap.c b/src/xkb/XKBGetMap.c +index 86ecf9d..af93a5c 100644 +--- a/src/xkb/XKBGetMap.c ++++ b/src/xkb/XKBGetMap.c +@@ -305,8 +305,10 @@ register int i; + xkbBehaviorWireDesc *wire; + + if ( rep->totalKeyBehaviors>0 ) { ++ int size = xkb->max_key_code + 1; ++ if ( ((int) rep->firstKeyBehavior + rep->nKeyBehaviors) > size) ++ return BadLength; + if ( xkb->server->behaviors == NULL ) { +- int size = xkb->max_key_code+1; + xkb->server->behaviors = _XkbTypedCalloc(size,XkbBehavior); + if (xkb->server->behaviors==NULL) + return BadAlloc; +@@ -318,7 +320,7 @@ xkbBehaviorWireDesc *wire; + for (i=0;itotalKeyBehaviors;i++) { + wire= (xkbBehaviorWireDesc *)_XkbGetReadBufferPtr(buf, + SIZEOF(xkbBehaviorWireDesc)); +- if (wire==NULL) ++ if (wire==NULL || wire->key >= size) + return BadLength; + xkb->server->behaviors[wire->key].type= wire->type; + xkb->server->behaviors[wire->key].data= wire->data; +-- +1.7.9.2 + +From b837305efa896d4bab4932faffb30d53cec546a3 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sat, 2 Mar 2013 10:51:51 -0800 +Subject: [PATCH:libX11 15/38] unvalidated index in _XkbReadModifierMap() + [CVE-2013-1997 8/15] + +If the X server returns modifier map indexes outside the range of the number +of keys it told us to allocate, out of bounds memory writes could occur. + +Reported-by: Ilja Van Sprundel +Signed-off-by: Alan Coopersmith +Reviewed-by: Matthieu Herrb +--- + src/xkb/XKBGetMap.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/xkb/XKBGetMap.c b/src/xkb/XKBGetMap.c +index af93a5c..a68455b 100644 +--- a/src/xkb/XKBGetMap.c ++++ b/src/xkb/XKBGetMap.c +@@ -390,6 +390,9 @@ register int i; + unsigned char *wire; + + if ( rep->totalModMapKeys>0 ) { ++ if ( ((int)rep->firstModMapKey + rep->nModMapKeys) > ++ (xkb->max_key_code + 1)) ++ return BadLength; + if ((xkb->map->modmap==NULL)&& + (XkbAllocClientMap(xkb,XkbModifierMapMask,0)!=Success)) { + return BadAlloc; +@@ -402,6 +405,8 @@ unsigned char *wire; + if (!wire) + return BadLength; + for (i=0;itotalModMapKeys;i++,wire+=2) { ++ if (wire[0] > xkb->max_key_code || wire[1] > xkb->max_key_code) ++ return BadLength; + xkb->map->modmap[wire[0]]= wire[1]; + } + } +-- +1.7.9.2 + +From d71c0d7d138f8d15e7f4cfe747329405f0644423 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sat, 2 Mar 2013 11:04:44 -0800 +Subject: [PATCH:libX11 16/38] unvalidated index in + _XkbReadExplicitComponents() [CVE-2013-1997 + 9/15] + +If the X server returns key indexes outside the range of the number of +keys it told us to allocate, out of bounds memory writes could occur. + +Reported-by: Ilja Van Sprundel +Signed-off-by: Alan Coopersmith +Reviewed-by: Matthieu Herrb +--- + src/xkb/XKBGetMap.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/xkb/XKBGetMap.c b/src/xkb/XKBGetMap.c +index a68455b..ea77f2a 100644 +--- a/src/xkb/XKBGetMap.c ++++ b/src/xkb/XKBGetMap.c +@@ -362,8 +362,10 @@ register int i; + unsigned char *wire; + + if ( rep->totalKeyExplicit>0 ) { ++ int size = xkb->max_key_code + 1; ++ if ( ((int) rep->firstKeyExplicit + rep->nKeyExplicit) > size) ++ return BadLength; + if ( xkb->server->explicit == NULL ) { +- int size = xkb->max_key_code+1; + xkb->server->explicit = _XkbTypedCalloc(size,unsigned char); + if (xkb->server->explicit==NULL) + return BadAlloc; +@@ -377,6 +379,8 @@ unsigned char *wire; + if (!wire) + return BadLength; + for (i=0;itotalKeyExplicit;i++,wire+=2) { ++ if (wire[0] > xkb->max_key_code || wire[1] > xkb->max_key_code) ++ return BadLength; + xkb->server->explicit[wire[0]]= wire[1]; + } + } +-- +1.7.9.2 + +From fb927b6dbc0172c2ca63b5ad243bfb98bb61fc4c Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sat, 2 Mar 2013 11:01:04 -0800 +Subject: [PATCH:libX11 17/38] unvalidated index in _XkbReadVirtualModMap() + [CVE-2013-1997 10/15] + +If the X server returns modifier map indexes outside the range of the number +of keys it told us to allocate, out of bounds memory writes could occur. + +Reported-by: Ilja Van Sprundel +Signed-off-by: Alan Coopersmith +Reviewed-by: Matthieu Herrb +--- + src/xkb/XKBGetMap.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/xkb/XKBGetMap.c b/src/xkb/XKBGetMap.c +index ea77f2a..5551298 100644 +--- a/src/xkb/XKBGetMap.c ++++ b/src/xkb/XKBGetMap.c +@@ -425,6 +425,9 @@ xkbVModMapWireDesc * wire; + XkbServerMapPtr srv; + + if ( rep->totalVModMapKeys>0 ) { ++ if (((int) rep->firstVModMapKey + rep->nVModMapKeys) ++ > xkb->max_key_code) ++ return BadLength; + if (((xkb->server==NULL)||(xkb->server->vmodmap==NULL))&& + (XkbAllocServerMap(xkb,XkbVirtualModMapMask,0)!=Success)) { + return BadAlloc; +-- +1.7.9.2 + +From f06f3cdc343fd6d42021dba055f080b617432301 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sat, 2 Mar 2013 11:11:08 -0800 +Subject: [PATCH:libX11 18/38] unvalidated index/length in + _XkbReadGetNamesReply() [CVE-2013-1997 11/15] + +If the X server returns key name indexes outside the range of the number +of keys it told us to allocate, out of bounds memory writes could occur. + +Reported-by: Ilja Van Sprundel +Signed-off-by: Alan Coopersmith +Reviewed-by: Matthieu Herrb +--- + src/xkb/XKBNames.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/xkb/XKBNames.c b/src/xkb/XKBNames.c +index 0276c05..0f1e48e 100644 +--- a/src/xkb/XKBNames.c ++++ b/src/xkb/XKBNames.c +@@ -180,6 +180,8 @@ _XkbReadGetNamesReply( Display * dpy, + nKeys= xkb->max_key_code+1; + names->keys= _XkbTypedCalloc(nKeys,XkbKeyNameRec); + } ++ else if ( ((int)rep->firstKey + rep->nKeys) > xkb->max_key_code) ++ goto BAILOUT; + if (names->keys!=NULL) { + if (!_XkbCopyFromReadBuffer(&buf, + (char *)&names->keys[rep->firstKey], +-- +1.7.9.2 + +From d851a64b0704f79550a9507a34d057c7415f6516 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sat, 2 Mar 2013 11:25:25 -0800 +Subject: [PATCH:libX11 19/38] unvalidated length in _XimXGetReadData() + [CVE-2013-1997 12/15] + +Check the provided buffer size against the amount of data we're going to +write into it, not against the reported length from the ClientMessage. + +Reported-by: Ilja Van Sprundel +Signed-off-by: Alan Coopersmith +Reviewed-by: Matthieu Herrb +--- + modules/im/ximcp/imTrX.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/modules/im/ximcp/imTrX.c b/modules/im/ximcp/imTrX.c +index 1412d70..76ff20e 100644 +--- a/modules/im/ximcp/imTrX.c ++++ b/modules/im/ximcp/imTrX.c +@@ -372,7 +372,7 @@ _XimXGetReadData( + XFree(prop_ret); + return False; + } +- if (buf_len >= length) { ++ if (buf_len >= (int)nitems) { + (void)memcpy(buf, prop_ret, (int)nitems); + *ret_len = (int)nitems; + if (bytes_after_ret > 0) { +-- +1.7.9.2 + +From 59ba5744cdb8831e53f6340279d9841a037c48bc Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sat, 2 Mar 2013 15:08:21 -0800 +Subject: [PATCH:libX11 30/38] Avoid overflows in XListFonts() [CVE-2013-1997 + 13/15] + +Ensure that when breaking the returned list into individual strings, +we don't walk past the end of allocated memory to write the '\0' bytes + +Signed-off-by: Alan Coopersmith +Reviewed-by: Matthieu Herrb +--- + src/FontNames.c | 35 ++++++++++++++++++++++------------- + 1 file changed, 22 insertions(+), 13 deletions(-) + +diff --git a/src/FontNames.c b/src/FontNames.c +index 3018cf2..b5bc7b4 100644 +--- a/src/FontNames.c ++++ b/src/FontNames.c +@@ -29,6 +29,7 @@ in this Software without prior written authorization from The Open Group. + #include + #endif + #include "Xlibint.h" ++#include + + char ** + XListFonts( +@@ -40,11 +41,13 @@ int *actualCount) /* RETURN */ + register long nbytes; + register unsigned i; + register int length; +- char **flist; +- char *ch; ++ char **flist = NULL; ++ char *ch = NULL; ++ char *chend; ++ int count = 0; + xListFontsReply rep; + register xListFontsReq *req; +- register long rlen; ++ unsigned long rlen; + + LockDisplay(dpy); + GetReq(ListFonts, req); +@@ -62,15 +65,17 @@ int *actualCount) /* RETURN */ + } + + if (rep.nFonts) { +- flist = (char **)Xmalloc ((unsigned)rep.nFonts * sizeof(char *)); +- rlen = rep.length << 2; +- ch = (char *) Xmalloc((unsigned) (rlen + 1)); ++ flist = Xmalloc (rep.nFonts * sizeof(char *)); ++ if (rep.length < (LONG_MAX >> 2)) { ++ rlen = rep.length << 2; ++ ch = Xmalloc(rlen + 1); + /* +1 to leave room for last null-terminator */ ++ } + + if ((! flist) || (! ch)) { + if (flist) Xfree((char *) flist); + if (ch) Xfree(ch); +- _XEatData(dpy, (unsigned long) rlen); ++ _XEatDataWords(dpy, rep.length); + *actualCount = 0; + UnlockDisplay(dpy); + SyncHandle(); +@@ -81,17 +86,21 @@ int *actualCount) /* RETURN */ + /* + * unpack into null terminated strings. + */ ++ chend = ch + (rlen + 1); + length = *(unsigned char *)ch; + *ch = 1; /* make sure it is non-zero for XFreeFontNames */ + for (i = 0; i < rep.nFonts; i++) { +- flist[i] = ch + 1; /* skip over length */ +- ch += length + 1; /* find next length ... */ +- length = *(unsigned char *)ch; +- *ch = '\0'; /* and replace with null-termination */ ++ if (ch + length < chend) { ++ flist[i] = ch + 1; /* skip over length */ ++ ch += length + 1; /* find next length ... */ ++ length = *(unsigned char *)ch; ++ *ch = '\0'; /* and replace with null-termination */ ++ count++; ++ } else ++ flist[i] = NULL; + } + } +- else flist = (char **) NULL; +- *actualCount = rep.nFonts; ++ *actualCount = count; + UnlockDisplay(dpy); + SyncHandle(); + return (flist); +-- +1.7.9.2 + +From b5686ac6ad36e7742f8bba5b906bf2c57ba18955 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sat, 2 Mar 2013 15:08:21 -0800 +Subject: [PATCH:libX11 31/38] Avoid overflows in XGetFontPath() + [CVE-2013-1997 14/15] + +Ensure that when breaking the returned list into individual strings, +we don't walk past the end of allocated memory to write the '\0' bytes + +Signed-off-by: Alan Coopersmith +Reviewed-by: Matthieu Herrb +--- + src/GetFPath.c | 36 ++++++++++++++++++++++-------------- + 1 file changed, 22 insertions(+), 14 deletions(-) + +diff --git a/src/GetFPath.c b/src/GetFPath.c +index 7d497c9..abd4a5d 100644 +--- a/src/GetFPath.c ++++ b/src/GetFPath.c +@@ -28,15 +28,18 @@ in this Software without prior written authorization from The Open Group. + #include + #endif + #include "Xlibint.h" ++#include + + char **XGetFontPath( + register Display *dpy, + int *npaths) /* RETURN */ + { + xGetFontPathReply rep; +- register long nbytes; +- char **flist; +- char *ch; ++ unsigned long nbytes; ++ char **flist = NULL; ++ char *ch = NULL; ++ char *chend; ++ int count = 0; + register unsigned i; + register int length; + register xReq *req; +@@ -46,16 +49,17 @@ char **XGetFontPath( + (void) _XReply (dpy, (xReply *) &rep, 0, xFalse); + + if (rep.nPaths) { +- flist = (char **) +- Xmalloc((unsigned) rep.nPaths * sizeof (char *)); +- nbytes = (long)rep.length << 2; +- ch = (char *) Xmalloc ((unsigned) (nbytes + 1)); ++ flist = Xmalloc(rep.nPaths * sizeof (char *)); ++ if (rep.length < (LONG_MAX >> 2)) { ++ nbytes = (unsigned long) rep.length << 2; ++ ch = Xmalloc (nbytes + 1); + /* +1 to leave room for last null-terminator */ ++ } + + if ((! flist) || (! ch)) { + if (flist) Xfree((char *) flist); + if (ch) Xfree(ch); +- _XEatData(dpy, (unsigned long) nbytes); ++ _XEatDataWords(dpy, rep.length); + UnlockDisplay(dpy); + SyncHandle(); + return (char **) NULL; +@@ -65,16 +69,20 @@ char **XGetFontPath( + /* + * unpack into null terminated strings. + */ ++ chend = ch + (nbytes + 1); + length = *ch; + for (i = 0; i < rep.nPaths; i++) { +- flist[i] = ch+1; /* skip over length */ +- ch += length + 1; /* find next length ... */ +- length = *ch; +- *ch = '\0'; /* and replace with null-termination */ ++ if (ch + length < chend) { ++ flist[i] = ch+1; /* skip over length */ ++ ch += length + 1; /* find next length ... */ ++ length = *ch; ++ *ch = '\0'; /* and replace with null-termination */ ++ count++; ++ } else ++ flist[i] = NULL; + } + } +- else flist = NULL; +- *npaths = rep.nPaths; ++ *npaths = count; + UnlockDisplay(dpy); + SyncHandle(); + return (flist); +-- +1.7.9.2 + +From 910875c83c9e6741aba258f44f94b3d69f804d00 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sat, 2 Mar 2013 15:08:21 -0800 +Subject: [PATCH:libX11 32/38] Avoid overflows in XListExtensions() + [CVE-2013-1997 15/15] + +Ensure that when breaking the returned list into individual strings, +we don't walk past the end of allocated memory to write the '\0' bytes + +Signed-off-by: Alan Coopersmith +Reviewed-by: Matthieu Herrb +--- + src/ListExt.c | 36 ++++++++++++++++++++++-------------- + 1 file changed, 22 insertions(+), 14 deletions(-) + +diff --git a/src/ListExt.c b/src/ListExt.c +index 16b522e..e925c47 100644 +--- a/src/ListExt.c ++++ b/src/ListExt.c +@@ -28,18 +28,21 @@ in this Software without prior written authorization from The Open Group. + #include + #endif + #include "Xlibint.h" ++#include + + char **XListExtensions( + register Display *dpy, + int *nextensions) /* RETURN */ + { + xListExtensionsReply rep; +- char **list; +- char *ch; ++ char **list = NULL; ++ char *ch = NULL; ++ char *chend; ++ int count = 0; + register unsigned i; + register int length; + register xReq *req; +- register long rlen; ++ unsigned long rlen; + + LockDisplay(dpy); + GetEmptyReq (ListExtensions, req); +@@ -51,16 +54,17 @@ char **XListExtensions( + } + + if (rep.nExtensions) { +- list = (char **) Xmalloc ( +- (unsigned)(rep.nExtensions * sizeof (char *))); +- rlen = rep.length << 2; +- ch = (char *) Xmalloc ((unsigned) rlen + 1); ++ list = Xmalloc (rep.nExtensions * sizeof (char *)); ++ if (rep.length < (LONG_MAX >> 2)) { ++ rlen = rep.length << 2; ++ ch = Xmalloc (rlen + 1); + /* +1 to leave room for last null-terminator */ ++ } + + if ((!list) || (!ch)) { + if (list) Xfree((char *) list); + if (ch) Xfree((char *) ch); +- _XEatData(dpy, (unsigned long) rlen); ++ _XEatDataWords(dpy, rep.length); + UnlockDisplay(dpy); + SyncHandle(); + return (char **) NULL; +@@ -70,17 +74,21 @@ char **XListExtensions( + /* + * unpack into null terminated strings. + */ ++ chend = ch + (rlen + 1); + length = *ch; + for (i = 0; i < rep.nExtensions; i++) { +- list[i] = ch+1; /* skip over length */ +- ch += length + 1; /* find next length ... */ +- length = *ch; +- *ch = '\0'; /* and replace with null-termination */ ++ if (ch + length < chend) { ++ list[i] = ch+1; /* skip over length */ ++ ch += length + 1; /* find next length ... */ ++ length = *ch; ++ *ch = '\0'; /* and replace with null-termination */ ++ count++; ++ } else ++ list[i] = NULL; + } + } +- else list = (char **) NULL; + +- *nextensions = rep.nExtensions; ++ *nextensions = count; + UnlockDisplay(dpy); + SyncHandle(); + return (list); +-- +1.7.9.2 + +From 134944bfb0963151e4e65b9b17c5431a41acd28e Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 31 Mar 2013 12:22:35 -0700 +Subject: [PATCH:libX11 37/38] _XkbReadGetMapReply: reject maxKeyCodes smaller + than the minKeyCode + +Various other bounds checks in the code assume this is true, so +enforce it when we first get the data from the X server. + +Signed-off-by: Alan Coopersmith +--- + src/xkb/XKBGetMap.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/xkb/XKBGetMap.c b/src/xkb/XKBGetMap.c +index d4cc199..862807a 100644 +--- a/src/xkb/XKBGetMap.c ++++ b/src/xkb/XKBGetMap.c +@@ -482,6 +482,8 @@ unsigned mask; + + if ( xkb->device_spec == XkbUseCoreKbd ) + xkb->device_spec= rep->deviceID; ++ if ( rep->maxKeyCode < rep->minKeyCode ) ++ return BadImplementation; + xkb->min_key_code = rep->minKeyCode; + xkb->max_key_code = rep->maxKeyCode; + +-- +1.7.9.2 +