Commit 50e80a06 authored by Mike DePaulo's avatar Mike DePaulo Committed by Mike Gabriel

CVE-2014-0210: unvalidated lengths when reading replies from font server from…

CVE-2014-0210: unvalidated lengths when reading replies from font server from xorg/lib/libXfont commit cbb64aef35960b2882be721f4b8fbaa0fb649d12 Functions to handle replies to font server requests were casting replies from the generic form to reply specific structs without first checking that the reply was at least as long as the struct being cast to.
parent a2c7cd9f
...@@ -94,6 +94,12 @@ in this Software without prior written authorization from The Open Group. ...@@ -94,6 +94,12 @@ in this Software without prior written authorization from The Open Group.
(pci)->descent || \ (pci)->descent || \
(pci)->characterWidth) (pci)->characterWidth)
/*
* SIZEOF(r) is in bytes, length fields in the protocol are in 32-bit words,
* so this converts for doing size comparisons.
*/
#define LENGTHOF(r) (SIZEOF(r) >> 2)
extern void ErrorF(const char *f, ...); extern void ErrorF(const char *f, ...);
static int fs_read_glyphs ( FontPathElementPtr fpe, FSBlockDataPtr blockrec ); static int fs_read_glyphs ( FontPathElementPtr fpe, FSBlockDataPtr blockrec );
...@@ -209,9 +215,22 @@ _fs_add_rep_log (FSFpePtr conn, fsGenericReply *rep) ...@@ -209,9 +215,22 @@ _fs_add_rep_log (FSFpePtr conn, fsGenericReply *rep)
rep->sequenceNumber, rep->sequenceNumber,
conn->reqbuffer[i].opcode); conn->reqbuffer[i].opcode);
} }
#define _fs_reply_failed(rep, name, op) do { \
if (rep) { \
if (rep->type == FS_Error) \
fprintf (stderr, "Error: %d Request: %s\n", \
((fsError *)rep)->request, #name); \
else \
fprintf (stderr, "Bad Length for %s Reply: %d %s %d\n", \
#name, rep->length, op, LENGTHOF(name)); \
} \
} while (0)
#else #else
#define _fs_add_req_log(conn,op) ((conn)->current_seq++) #define _fs_add_req_log(conn,op) ((conn)->current_seq++)
#define _fs_add_rep_log(conn,rep) #define _fs_add_rep_log(conn,rep)
#define _fs_reply_failed(rep,name,op)
#endif #endif
static Bool static Bool
...@@ -693,13 +712,15 @@ fs_read_open_font(FontPathElementPtr fpe, FSBlockDataPtr blockrec) ...@@ -693,13 +712,15 @@ fs_read_open_font(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
int ret; int ret;
rep = (fsOpenBitmapFontReply *) fs_get_reply (conn, &ret); rep = (fsOpenBitmapFontReply *) fs_get_reply (conn, &ret);
if (!rep || rep->type == FS_Error) if (!rep || rep->type == FS_Error ||
(rep->length != LENGTHOF(fsOpenBitmapFontReply)))
{ {
if (ret == FSIO_BLOCK) if (ret == FSIO_BLOCK)
return StillWorking; return StillWorking;
if (rep) if (rep)
_fs_done_read (conn, rep->length << 2); _fs_done_read (conn, rep->length << 2);
fs_cleanup_bfont (bfont); fs_cleanup_bfont (bfont);
_fs_reply_failed (rep, fsOpenBitmapFontReply, "!=");
return BadFontName; return BadFontName;
} }
...@@ -835,13 +856,15 @@ fs_read_query_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec) ...@@ -835,13 +856,15 @@ fs_read_query_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
int ret; int ret;
rep = (fsQueryXInfoReply *) fs_get_reply (conn, &ret); rep = (fsQueryXInfoReply *) fs_get_reply (conn, &ret);
if (!rep || rep->type == FS_Error) if (!rep || rep->type == FS_Error ||
(rep->length < LENGTHOF(fsQueryXInfoReply)))
{ {
if (ret == FSIO_BLOCK) if (ret == FSIO_BLOCK)
return StillWorking; return StillWorking;
if (rep) if (rep)
_fs_done_read (conn, rep->length << 2); _fs_done_read (conn, rep->length << 2);
fs_cleanup_bfont (bfont); fs_cleanup_bfont (bfont);
_fs_reply_failed (rep, fsQueryXInfoReply, "<");
return BadFontName; return BadFontName;
} }
...@@ -962,13 +985,15 @@ fs_read_extent_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec) ...@@ -962,13 +985,15 @@ fs_read_extent_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
FontInfoRec *fi = &bfont->pfont->info; FontInfoRec *fi = &bfont->pfont->info;
rep = (fsQueryXExtents16Reply *) fs_get_reply (conn, &ret); rep = (fsQueryXExtents16Reply *) fs_get_reply (conn, &ret);
if (!rep || rep->type == FS_Error) if (!rep || rep->type == FS_Error ||
(rep->length < LENGTHOF(fsQueryXExtents16Reply)))
{ {
if (ret == FSIO_BLOCK) if (ret == FSIO_BLOCK)
return StillWorking; return StillWorking;
if (rep) if (rep)
_fs_done_read (conn, rep->length << 2); _fs_done_read (conn, rep->length << 2);
fs_cleanup_bfont (bfont); fs_cleanup_bfont (bfont);
_fs_reply_failed (rep, fsQueryXExtents16Reply, "<");
return BadFontName; return BadFontName;
} }
...@@ -1833,13 +1858,15 @@ fs_read_glyphs(FontPathElementPtr fpe, FSBlockDataPtr blockrec) ...@@ -1833,13 +1858,15 @@ fs_read_glyphs(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
unsigned long minchar, maxchar; unsigned long minchar, maxchar;
rep = (fsQueryXBitmaps16Reply *) fs_get_reply (conn, &ret); rep = (fsQueryXBitmaps16Reply *) fs_get_reply (conn, &ret);
if (!rep || rep->type == FS_Error) if (!rep || rep->type == FS_Error ||
(rep->length < LENGTHOF(fsQueryXBitmaps16Reply)))
{ {
if (ret == FSIO_BLOCK) if (ret == FSIO_BLOCK)
return StillWorking; return StillWorking;
if (rep) if (rep)
_fs_done_read (conn, rep->length << 2); _fs_done_read (conn, rep->length << 2);
err = AllocError; err = AllocError;
_fs_reply_failed (rep, fsQueryXBitmaps16Reply, "<");
goto bail; goto bail;
} }
...@@ -2243,12 +2270,14 @@ fs_read_list(FontPathElementPtr fpe, FSBlockDataPtr blockrec) ...@@ -2243,12 +2270,14 @@ fs_read_list(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
int err; int err;
rep = (fsListFontsReply *) fs_get_reply (conn, &ret); rep = (fsListFontsReply *) fs_get_reply (conn, &ret);
if (!rep || rep->type == FS_Error) if (!rep || rep->type == FS_Error ||
(rep->length < LENGTHOF(fsListFontsReply)))
{ {
if (ret == FSIO_BLOCK) if (ret == FSIO_BLOCK)
return StillWorking; return StillWorking;
if (rep) if (rep)
_fs_done_read (conn, rep->length << 2); _fs_done_read (conn, rep->length << 2);
_fs_reply_failed (rep, fsListFontsReply, "<");
return AllocError; return AllocError;
} }
data = (char *) rep + SIZEOF (fsListFontsReply); data = (char *) rep + SIZEOF (fsListFontsReply);
...@@ -2366,12 +2395,15 @@ fs_read_list_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec) ...@@ -2366,12 +2395,15 @@ fs_read_list_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
_fs_free_props (&binfo->info); _fs_free_props (&binfo->info);
rep = (fsListFontsWithXInfoReply *) fs_get_reply (conn, &ret); rep = (fsListFontsWithXInfoReply *) fs_get_reply (conn, &ret);
if (!rep || rep->type == FS_Error) if (!rep || rep->type == FS_Error ||
((rep->nameLength != 0) &&
(rep->length < LENGTHOF(fsListFontsWithXInfoReply))))
{ {
if (ret == FSIO_BLOCK) if (ret == FSIO_BLOCK)
return StillWorking; return StillWorking;
binfo->status = FS_LFWI_FINISHED; binfo->status = FS_LFWI_FINISHED;
err = AllocError; err = AllocError;
_fs_reply_failed (rep, fsListFontsWithXInfoReply, "<");
goto done; goto done;
} }
/* /*
......
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