aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike DePaulo <mikedep333@gmail.com>2015-02-08 21:03:33 -0500
committerMihai Moldovan <ionic@ionic.de>2015-02-16 05:54:00 +0100
commit31322c2bd9be76493a5a04a23ea68e063fe3b7e6 (patch)
tree95ad34e6d40c0d8687728ee4c682341d2e41c7d2
parentc0d0e373d4c42c7813b1955fc18f5c9f63c725e0 (diff)
downloadnx-libs-31322c2bd9be76493a5a04a23ea68e063fe3b7e6.tar.gz
nx-libs-31322c2bd9be76493a5a04a23ea68e063fe3b7e6.tar.bz2
nx-libs-31322c2bd9be76493a5a04a23ea68e063fe3b7e6.zip
CVE-2014-0210: unvalidated length in _fs_recv_conn_setup() from xorg/lib/libXfont commit 891e084b26837162b12f841060086a105edde86d
The connection setup reply from the font server can include a list of alternate servers to contact if this font server stops working. The reply specifies a total size of all the font server names, and then provides a list of names. _fs_recv_conn_setup() allocated the specified total size for copying the names to, but didn't check to make sure it wasn't copying more data to that buffer than the size it had allocated. v2: use xfree() instead of free() for nx-libs 3.6.x (Mihai Moldovan)
-rw-r--r--nx-X11/lib/font/fc/fserve.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/nx-X11/lib/font/fc/fserve.c b/nx-X11/lib/font/fc/fserve.c
index 0d792c7e3..86b5753ef 100644
--- a/nx-X11/lib/font/fc/fserve.c
+++ b/nx-X11/lib/font/fc/fserve.c
@@ -2985,7 +2985,7 @@ _fs_recv_conn_setup (FSFpePtr conn)
int ret;
fsConnSetup *setup;
FSFpeAltPtr alts;
- int i, alt_len;
+ unsigned int i, alt_len;
int setup_len;
char *alt_save, *alt_names;
@@ -3012,9 +3012,9 @@ _fs_recv_conn_setup (FSFpePtr conn)
}
if (setup->num_alternates)
{
+ size_t alt_name_len = setup->alternate_len << 2;
alts = (FSFpeAltPtr) xalloc (setup->num_alternates *
- sizeof (FSFpeAltRec) +
- (setup->alternate_len << 2));
+ sizeof (FSFpeAltRec) + alt_name_len);
if (alts)
{
alt_names = (char *) (setup + 1);
@@ -3023,10 +3023,25 @@ _fs_recv_conn_setup (FSFpePtr conn)
{
alts[i].subset = alt_names[0];
alt_len = alt_names[1];
+ if (alt_len >= alt_name_len) {
+ /*
+ * Length is longer than setup->alternate_len
+ * told us to allocate room for, assume entire
+ * alternate list is corrupted.
+ */
+#ifdef DEBUG
+ fprintf (stderr,
+ "invalid alt list (length %lx >= %lx)\n",
+ (long) alt_len, (long) alt_name_len);
+#endif
+ xfree(alts);
+ return FSIO_ERROR;
+ }
alts[i].name = alt_save;
memcpy (alt_save, alt_names + 2, alt_len);
alt_save[alt_len] = '\0';
alt_save += alt_len + 1;
+ alt_name_len -= alt_len + 1;
alt_names += _fs_pad_length (alt_len + 2);
}
conn->numAlts = setup->num_alternates;