|
|
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 |
|