Blame SOURCES/0003-CVE-2014-0210-unvalidated-length-in-_fs_recv_conn_se.patch

cf1e18
From 891e084b26837162b12f841060086a105edde86d Mon Sep 17 00:00:00 2001
cf1e18
From: Alan Coopersmith <alan.coopersmith@oracle.com>
cf1e18
Date: Fri, 25 Apr 2014 23:02:00 -0700
cf1e18
Subject: [PATCH 03/12] CVE-2014-0210: unvalidated length in _fs_recv_conn_setup()
cf1e18
cf1e18
The connection setup reply from the font server can include a list
cf1e18
of alternate servers to contact if this font server stops working.
cf1e18
cf1e18
The reply specifies a total size of all the font server names, and
cf1e18
then provides a list of names. _fs_recv_conn_setup() allocated the
cf1e18
specified total size for copying the names to, but didn't check to
cf1e18
make sure it wasn't copying more data to that buffer than the size
cf1e18
it had allocated.
cf1e18
cf1e18
Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
cf1e18
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
cf1e18
Reviewed-by: Adam Jackson <ajax@redhat.com>
cf1e18
Reviewed-by: Matthieu Herrb <matthieu@herrb.eu>
cf1e18
---
cf1e18
 src/fc/fserve.c |   20 ++++++++++++++++++--
cf1e18
 1 files changed, 18 insertions(+), 2 deletions(-)
cf1e18
cf1e18
diff --git a/src/fc/fserve.c b/src/fc/fserve.c
cf1e18
index 3585951..aa9acdb 100644
cf1e18
--- a/src/fc/fserve.c
cf1e18
+++ b/src/fc/fserve.c
cf1e18
@@ -2784,7 +2784,7 @@ _fs_recv_conn_setup (FSFpePtr conn)
cf1e18
     int			ret = FSIO_ERROR;
cf1e18
     fsConnSetup		*setup;
cf1e18
     FSFpeAltPtr		alts;
cf1e18
-    int			i, alt_len;
cf1e18
+    unsigned int	i, alt_len;
cf1e18
     int			setup_len;
cf1e18
     char		*alt_save, *alt_names;
cf1e18
 
cf1e18
@@ -2811,8 +2811,9 @@ _fs_recv_conn_setup (FSFpePtr conn)
cf1e18
 	}
cf1e18
 	if (setup->num_alternates)
cf1e18
 	{
cf1e18
+	    size_t alt_name_len = setup->alternate_len << 2;
cf1e18
 	    alts = malloc (setup->num_alternates * sizeof (FSFpeAltRec) +
cf1e18
-			   (setup->alternate_len << 2));
cf1e18
+			   alt_name_len);
cf1e18
 	    if (alts)
cf1e18
 	    {
cf1e18
 		alt_names = (char *) (setup + 1);
cf1e18
@@ -2821,10 +2822,25 @@ _fs_recv_conn_setup (FSFpePtr conn)
cf1e18
 		{
cf1e18
 		    alts[i].subset = alt_names[0];
cf1e18
 		    alt_len = alt_names[1];
cf1e18
+		    if (alt_len >= alt_name_len) {
cf1e18
+			/*
cf1e18
+			 * Length is longer than setup->alternate_len
cf1e18
+			 * told us to allocate room for, assume entire
cf1e18
+			 * alternate list is corrupted.
cf1e18
+			 */
cf1e18
+#ifdef DEBUG
cf1e18
+			fprintf (stderr,
cf1e18
+				 "invalid alt list (length %lx >= %lx)\n",
cf1e18
+				 (long) alt_len, (long) alt_name_len);
cf1e18
+#endif
cf1e18
+			free(alts);
cf1e18
+			return FSIO_ERROR;
cf1e18
+		    }
cf1e18
 		    alts[i].name = alt_save;
cf1e18
 		    memcpy (alt_save, alt_names + 2, alt_len);
cf1e18
 		    alt_save[alt_len] = '\0';
cf1e18
 		    alt_save += alt_len + 1;
cf1e18
+		    alt_name_len -= alt_len + 1;
cf1e18
 		    alt_names += _fs_pad_length (alt_len + 2);
cf1e18
 		}
cf1e18
 		conn->numAlts = setup->num_alternates;
cf1e18
-- 
cf1e18
1.7.1
cf1e18