aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike DePaulo <mikedep333@gmail.com>2015-02-08 21:39:55 -0500
committerMike Gabriel <mike.gabriel@das-netzwerkteam.de>2015-02-14 16:14:31 +0100
commit50e80a06c84375e39af02b24f01a949cb565a49d (patch)
tree3ffcfc72a62a256570ae21a32c7704e34663ab5e
parenta2c7cd9fef2d7d108e224ab47e77130dc98b249d (diff)
downloadnx-libs-50e80a06c84375e39af02b24f01a949cb565a49d.tar.gz
nx-libs-50e80a06c84375e39af02b24f01a949cb565a49d.tar.bz2
nx-libs-50e80a06c84375e39af02b24f01a949cb565a49d.zip
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.
-rw-r--r--nx-X11/lib/font/fc/fserve.c44
1 files changed, 38 insertions, 6 deletions
diff --git a/nx-X11/lib/font/fc/fserve.c b/nx-X11/lib/font/fc/fserve.c
index c159b2b46..ca10aa4ad 100644
--- a/nx-X11/lib/font/fc/fserve.c
+++ b/nx-X11/lib/font/fc/fserve.c
@@ -94,6 +94,12 @@ in this Software without prior written authorization from The Open Group.
(pci)->descent || \
(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, ...);
static int fs_read_glyphs ( FontPathElementPtr fpe, FSBlockDataPtr blockrec );
@@ -209,9 +215,22 @@ _fs_add_rep_log (FSFpePtr conn, fsGenericReply *rep)
rep->sequenceNumber,
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
#define _fs_add_req_log(conn,op) ((conn)->current_seq++)
#define _fs_add_rep_log(conn,rep)
+#define _fs_reply_failed(rep,name,op)
#endif
static Bool
@@ -693,13 +712,15 @@ fs_read_open_font(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
int 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)
return StillWorking;
if (rep)
_fs_done_read (conn, rep->length << 2);
fs_cleanup_bfont (bfont);
+ _fs_reply_failed (rep, fsOpenBitmapFontReply, "!=");
return BadFontName;
}
@@ -835,13 +856,15 @@ fs_read_query_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
int 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)
return StillWorking;
if (rep)
_fs_done_read (conn, rep->length << 2);
fs_cleanup_bfont (bfont);
+ _fs_reply_failed (rep, fsQueryXInfoReply, "<");
return BadFontName;
}
@@ -962,13 +985,15 @@ fs_read_extent_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
FontInfoRec *fi = &bfont->pfont->info;
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)
return StillWorking;
if (rep)
_fs_done_read (conn, rep->length << 2);
fs_cleanup_bfont (bfont);
+ _fs_reply_failed (rep, fsQueryXExtents16Reply, "<");
return BadFontName;
}
@@ -1833,13 +1858,15 @@ fs_read_glyphs(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
unsigned long minchar, maxchar;
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)
return StillWorking;
if (rep)
_fs_done_read (conn, rep->length << 2);
err = AllocError;
+ _fs_reply_failed (rep, fsQueryXBitmaps16Reply, "<");
goto bail;
}
@@ -2243,12 +2270,14 @@ fs_read_list(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
int err;
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)
return StillWorking;
if (rep)
_fs_done_read (conn, rep->length << 2);
+ _fs_reply_failed (rep, fsListFontsReply, "<");
return AllocError;
}
data = (char *) rep + SIZEOF (fsListFontsReply);
@@ -2366,12 +2395,15 @@ fs_read_list_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
_fs_free_props (&binfo->info);
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)
return StillWorking;
binfo->status = FS_LFWI_FINISHED;
err = AllocError;
+ _fs_reply_failed (rep, fsListFontsWithXInfoReply, "<");
goto done;
}
/*