Commit de2d3cb6 authored by Alan Coopersmith's avatar Alan Coopersmith Committed by Ulrich Sibiller

integer overflow in _XQueryFont() on 32-bit platforms [CVE-2013-1981 1/13]

If the CARD32 reply.nCharInfos * sizeof(XCharStruct) overflows an unsigned long, then too small of a buffer will be allocated for the data copied in from the reply. v2: Fix reply_left calculations, check calculated sizes fit in reply_left Reported-by: 's avatarIlja Van Sprundel <ivansprundel@ioactive.com> Signed-off-by: 's avatarAlan Coopersmith <alan.coopersmith@oracle.com> Signed-off-by: 's avatarJulien Cristau <jcristau@debian.org> Backported-to-NX-by: 's avatarUlrich Sibiller <uli42@gmx.de>
parent e8ada07f
...@@ -31,6 +31,7 @@ authorization from the X Consortium and the XFree86 Project. ...@@ -31,6 +31,7 @@ authorization from the X Consortium and the XFree86 Project.
#include <config.h> #include <config.h>
#endif #endif
#include "Xlibint.h" #include "Xlibint.h"
#include <limits.h>
#if defined(XF86BIGFONT) #if defined(XF86BIGFONT)
#define USE_XF86BIGFONT #define USE_XF86BIGFONT
...@@ -183,7 +184,8 @@ _XQueryFont ( ...@@ -183,7 +184,8 @@ _XQueryFont (
unsigned long seq) unsigned long seq)
{ {
register XFontStruct *fs; register XFontStruct *fs;
register long nbytes; unsigned long nbytes;
unsigned long reply_left; /* unused data words left in reply buffer */
xQueryFontReply reply; xQueryFontReply reply;
register xResourceReq *req; register xResourceReq *req;
register _XExtension *ext; register _XExtension *ext;
...@@ -211,9 +213,10 @@ _XQueryFont ( ...@@ -211,9 +213,10 @@ _XQueryFont (
} }
if (seq) if (seq)
DeqAsyncHandler(dpy, &async); DeqAsyncHandler(dpy, &async);
reply_left = reply.length -
((SIZEOF(xQueryFontReply) - SIZEOF(xReply)) >> 2);
if (! (fs = (XFontStruct *) Xmalloc (sizeof (XFontStruct)))) { if (! (fs = (XFontStruct *) Xmalloc (sizeof (XFontStruct)))) {
_XEatData(dpy, (unsigned long)(reply.nFontProps * SIZEOF(xFontProp) + _XEatDataWords(dpy, reply_left);
reply.nCharInfos * SIZEOF(xCharInfo)));
return (XFontStruct *)NULL; return (XFontStruct *)NULL;
} }
fs->ext_data = NULL; fs->ext_data = NULL;
...@@ -239,32 +242,42 @@ _XQueryFont ( ...@@ -239,32 +242,42 @@ _XQueryFont (
*/ */
fs->properties = NULL; fs->properties = NULL;
if (fs->n_properties > 0) { if (fs->n_properties > 0) {
nbytes = reply.nFontProps * sizeof(XFontProp); /* nFontProps is a CARD16 */
fs->properties = (XFontProp *) Xmalloc ((unsigned) nbytes);
nbytes = reply.nFontProps * SIZEOF(xFontProp); nbytes = reply.nFontProps * SIZEOF(xFontProp);
if ((nbytes >> 2) <= reply_left) {
size_t pbytes = reply.nFontProps * sizeof(XFontProp);
fs->properties = Xmalloc (pbytes);
}
if (! fs->properties) { if (! fs->properties) {
Xfree((char *) fs); Xfree((char *) fs);
_XEatData(dpy, (unsigned long) _XEatDataWords(dpy, reply_left);
(nbytes + reply.nCharInfos * SIZEOF(xCharInfo)));
return (XFontStruct *)NULL; return (XFontStruct *)NULL;
} }
_XRead32 (dpy, (long *)fs->properties, nbytes); _XRead32 (dpy, (long *)fs->properties, nbytes);
reply_left -= (nbytes >> 2);
} }
/* /*
* If no characters in font, then it is a bad font, but * If no characters in font, then it is a bad font, but
* shouldn't try to read nothing. * shouldn't try to read nothing.
*/ */
/* have to unpack charinfos on some machines (CRAY) */
fs->per_char = NULL; fs->per_char = NULL;
if (reply.nCharInfos > 0){ if (reply.nCharInfos > 0){
nbytes = reply.nCharInfos * sizeof(XCharStruct); /* nCharInfos is a CARD32 */
if (! (fs->per_char = (XCharStruct *) Xmalloc ((unsigned) nbytes))) { if (reply.nCharInfos < (INT_MAX / sizeof(XCharStruct))) {
nbytes = reply.nCharInfos * SIZEOF(xCharInfo);
if ((nbytes >> 2) <= reply_left) {
size_t cibytes = reply.nCharInfos * sizeof(XCharStruct);
fs->per_char = Xmalloc (cibytes);
}
}
if (! fs->per_char) {
if (fs->properties) Xfree((char *) fs->properties); if (fs->properties) Xfree((char *) fs->properties);
Xfree((char *) fs); Xfree((char *) fs);
_XEatData(dpy, (unsigned long) _XEatDataWords(dpy, reply_left);
(reply.nCharInfos * SIZEOF(xCharInfo)));
return (XFontStruct *)NULL; return (XFontStruct *)NULL;
} }
nbytes = reply.nCharInfos * SIZEOF(xCharInfo);
_XRead16 (dpy, (char *)fs->per_char, nbytes); _XRead16 (dpy, (char *)fs->per_char, nbytes);
} }
......
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