summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Coopersmith <alan.coopersmith@oracle.com>2014-04-25 23:02:00 -0700
committerAlan Coopersmith <alan.coopersmith@oracle.com>2014-05-12 23:31:28 -0700
commit891e084b26837162b12f841060086a105edde86d (patch)
tree0233b907ad7a1a980294e7c3247e04ba36963945
parent05c8020a49416dd8b7510cbba45ce4f3fc81a7dc (diff)
CVE-2014-0210: unvalidated length in _fs_recv_conn_setup()
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. Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com> Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com> Reviewed-by: Adam Jackson <ajax@redhat.com> Reviewed-by: Matthieu Herrb <matthieu@herrb.eu>
-rw-r--r--src/fc/fserve.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/src/fc/fserve.c b/src/fc/fserve.c
index 3585951..aa9acdb 100644
--- a/src/fc/fserve.c
+++ b/src/fc/fserve.c
@@ -2784,7 +2784,7 @@ _fs_recv_conn_setup (FSFpePtr conn)
int ret = FSIO_ERROR;
fsConnSetup *setup;
FSFpeAltPtr alts;
- int i, alt_len;
+ unsigned int i, alt_len;
int setup_len;
char *alt_save, *alt_names;
@@ -2811,8 +2811,9 @@ _fs_recv_conn_setup (FSFpePtr conn)
}
if (setup->num_alternates)
{
+ size_t alt_name_len = setup->alternate_len << 2;
alts = malloc (setup->num_alternates * sizeof (FSFpeAltRec) +
- (setup->alternate_len << 2));
+ alt_name_len);
if (alts)
{
alt_names = (char *) (setup + 1);
@@ -2821,10 +2822,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
+ free(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;