Blame SOURCES/0005-CVE-2014-0211-Integer-overflow-in-fs_get_reply-_fs_s.patch

cf1e18
From 0f1a5d372c143f91a602bdf10c917d7eabaee09b Mon Sep 17 00:00:00 2001
cf1e18
From: Alan Coopersmith <alan.coopersmith@oracle.com>
cf1e18
Date: Fri, 25 Apr 2014 23:02:25 -0700
cf1e18
Subject: [PATCH 05/12] CVE-2014-0211: Integer overflow in fs_get_reply/_fs_start_read
cf1e18
cf1e18
fs_get_reply() would take any reply size, multiply it by 4 and pass to
cf1e18
_fs_start_read.  If that size was bigger than the current reply buffer
cf1e18
size, _fs_start_read would add it to the existing buffer size plus the
cf1e18
buffer size increment constant and realloc the buffer to that result.
cf1e18
cf1e18
This math could overflow, causing the code to allocate a smaller
cf1e18
buffer than the amount it was about to read into that buffer from
cf1e18
the network.  It could also succeed, allowing the remote font server
cf1e18
to cause massive allocations in the X server, possibly using up all
cf1e18
the address space in a 32-bit X server, allowing the triggering of
cf1e18
other bugs in code that fails to handle malloc failure properly.
cf1e18
cf1e18
This patch protects against both problems, by disconnecting any
cf1e18
font server trying to feed us more than (the somewhat arbitrary)
cf1e18
64 mb in a single reply.
cf1e18
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 |   18 ++++++++++++++++++
cf1e18
 1 files changed, 18 insertions(+), 0 deletions(-)
cf1e18
cf1e18
diff --git a/src/fc/fserve.c b/src/fc/fserve.c
cf1e18
index f08028f..3abbacf 100644
cf1e18
--- a/src/fc/fserve.c
cf1e18
+++ b/src/fc/fserve.c
cf1e18
@@ -97,6 +97,9 @@ in this Software without prior written authorization from The Open Group.
cf1e18
  */
cf1e18
 #define LENGTHOF(r)	(SIZEOF(r) >> 2)
cf1e18
 
cf1e18
+/* Somewhat arbitrary limit on maximum reply size we'll try to read. */
cf1e18
+#define MAX_REPLY_LENGTH	((64 * 1024 * 1024) >> 2)
cf1e18
+
cf1e18
 extern void ErrorF(const char *f, ...);
cf1e18
 
cf1e18
 static int fs_read_glyphs ( FontPathElementPtr fpe, FSBlockDataPtr blockrec );
cf1e18
@@ -619,6 +622,21 @@ fs_get_reply (FSFpePtr conn, int *error)
cf1e18
 
cf1e18
     rep = (fsGenericReply *) buf;
cf1e18
 
cf1e18
+    /*
cf1e18
+     * Refuse to accept replies longer than a maximum reasonable length,
cf1e18
+     * before we pass to _fs_start_read, since it will try to resize the
cf1e18
+     * incoming connection buffer to this size.  Also avoids integer overflow
cf1e18
+     * on 32-bit systems.
cf1e18
+     */
cf1e18
+    if (rep->length > MAX_REPLY_LENGTH)
cf1e18
+    {
cf1e18
+	ErrorF("fserve: reply length %d > MAX_REPLY_LENGTH, disconnecting"
cf1e18
+	       " from font server\n", rep->length);
cf1e18
+	_fs_connection_died (conn);
cf1e18
+	*error = FSIO_ERROR;
cf1e18
+	return 0;
cf1e18
+    }
cf1e18
+
cf1e18
     ret = _fs_start_read (conn, rep->length << 2, &buf;;
cf1e18
     if (ret != FSIO_READY)
cf1e18
     {
cf1e18
-- 
cf1e18
1.7.1
cf1e18