--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/open-src/lib/libXfont/upstream-backports.patch Wed May 14 17:56:52 2014 -0700
@@ -0,0 +1,478 @@
+From c8855746aec2a9b732502da0ca3258b4e701c61a Mon Sep 17 00:00:00 2001
+From: Peter Harris <[email protected]>
+Date: Mon, 7 Apr 2014 14:25:02 -0400
+Subject: [PATCH:libXfont] Fix buffer read overrun
+
+"FreeType" is only eight bytes long. The atom "FreeType\x00\x??" is
+probably not what the author intended.
+
+Signed-off-by: Peter Harris <[email protected]>
+Reviewed-by: Alan Coopersmith <[email protected]>
+---
+ src/FreeType/ftfuncs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/FreeType/ftfuncs.c b/src/FreeType/ftfuncs.c
+index 65efefc..a4969d1 100644
+--- a/src/FreeType/ftfuncs.c
++++ b/src/FreeType/ftfuncs.c
+@@ -1867,7 +1867,7 @@ FreeTypeAddProperties(FTFontPtr font, FontScalablePtr vals, FontInfoPtr info,
+ i++;
+
+ info->props[i].name = MakeAtom("RASTERIZER_NAME", 15, TRUE);
+- info->props[i].value = MakeAtom("FreeType", 10, TRUE);
++ info->props[i].value = MakeAtom("FreeType", 8, TRUE);
+ info->isStringProp[i] = 1;
+ i++;
+
+--
+1.7.9.2
+
+From 371f8582a33235afa1b61d76e4fe98bdc9d7c083 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Sun, 20 Apr 2014 17:59:14 -0700
+Subject: [PATCH:libXfont 01/16] Check if pointer returned by BufFileCreate is
+ NULL before writing to it
+
+Fixes clang analyzer warning:
+
+bufio.c:165:13: warning: Access to field 'bufp' results in a dereference
+ of a null pointer (loaded from variable 'f')
+ f->bufp = f->buffer;
+ ~ ^
+
+Signed-off-by: Alan Coopersmith <[email protected]>
+Reviewed-by: Thomas Klausner <[email protected]>
+(cherry picked from commit c77a0784bdfc8c178f0742689cf6ae02a2fce37f)
+---
+ src/fontfile/bufio.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/src/fontfile/bufio.c b/src/fontfile/bufio.c
+index 34b7f36..d8d4f29 100644
+--- a/src/fontfile/bufio.c
++++ b/src/fontfile/bufio.c
+@@ -162,8 +162,10 @@ BufFileOpenWrite (int fd)
+ setmode(fd,O_BINARY);
+ #endif
+ f = BufFileCreate ((char *)(long) fd, 0, BufFileRawFlush, 0, BufFileFlush);
+- f->bufp = f->buffer;
+- f->left = BUFFILESIZE;
++ if (f != NULL) {
++ f->bufp = f->buffer;
++ f->left = BUFFILESIZE;
++ }
+ return f;
+ }
+
+--
+1.7.9.2
+
+From 0a37bf2d9977db81573f300b0dc203df8fe108b5 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Fri, 25 Apr 2014 23:01:11 -0700
+Subject: [PATCH:libXfont 05/16] CVE-2014-0209: integer overflow of realloc()
+ size in FontFileAddEntry()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+FontFileReadDirectory() opens a fonts.dir file, and reads over every
+line in an fscanf loop. For each successful entry read (font name,
+file name) a call is made to FontFileAddFontFile().
+
+FontFileAddFontFile() will add a font file entry (for the font name
+and file) each time it’s called, by calling FontFileAddEntry().
+FontFileAddEntry() will do the actual adding. If the table it has
+to add to is full, it will do a realloc, adding 100 more entries
+to the table size without checking to see if that will overflow the
+int used to store the size.
+
+Reported-by: Ilja Van Sprundel <[email protected]>
+Signed-off-by: Alan Coopersmith <[email protected]>
+Reviewed-by: Adam Jackson <[email protected]>
+Reviewed-by: Matthieu Herrb <[email protected]>
+(cherry picked from commit 2f5e57317339c526e6eaee1010b0e2ab8089c42e)
+---
+ src/fontfile/fontdir.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/src/fontfile/fontdir.c b/src/fontfile/fontdir.c
+index ef7ffa5..7271603 100644
+--- a/src/fontfile/fontdir.c
++++ b/src/fontfile/fontdir.c
+@@ -177,6 +177,11 @@ FontFileAddEntry(FontTablePtr table, FontEntryPtr prototype)
+ if (table->sorted)
+ return (FontEntryPtr) 0; /* "cannot" happen */
+ if (table->used == table->size) {
++ if (table->size >= ((INT32_MAX / sizeof(FontEntryRec)) - 100))
++ /* If we've read so many entries we're going to ask for 2gb
++ or more of memory, something is so wrong with this font
++ directory that we should just give up before we overflow. */
++ return NULL;
+ newsize = table->size + 100;
+ entry = realloc(table->entries, newsize * sizeof(FontEntryRec));
+ if (!entry)
+--
+1.7.9.2
+
+From 26643c0c3f4e53945516e20e00dfbb4d69a39c65 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Fri, 25 Apr 2014 23:01:48 -0700
+Subject: [PATCH:libXfont 06/16] CVE-2014-0209: integer overflow of realloc()
+ size in lexAlias()
+
+lexAlias() reads from a file in a loop. It does this by starting with a
+64 byte buffer. If that size limit is hit, it does a realloc of the
+buffer size << 1, basically doubling the needed length every time the
+length limit is hit.
+
+Eventually, this will shift out to 0 (for a length of ~4gig), and that
+length will be passed on to realloc(). A length of 0 (with a valid
+pointer) causes realloc to free the buffer on most POSIX platforms,
+but the caller will still have a pointer to it, leading to use after
+free issues.
+
+Reported-by: Ilja Van Sprundel <[email protected]>
+Signed-off-by: Alan Coopersmith <[email protected]>
+Reviewed-by: Adam Jackson <[email protected]>
+Reviewed-by: Matthieu Herrb <[email protected]>
+(cherry picked from commit 05c8020a49416dd8b7510cbba45ce4f3fc81a7dc)
+---
+ src/fontfile/dirfile.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/fontfile/dirfile.c b/src/fontfile/dirfile.c
+index 0d34db9..639310c 100644
+--- a/src/fontfile/dirfile.c
++++ b/src/fontfile/dirfile.c
+@@ -42,6 +42,7 @@ in this Software without prior written authorization from The Open Group.
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <errno.h>
++#include <limits.h>
+
+ static Bool AddFileNameAliases ( FontDirectoryPtr dir );
+ static int ReadFontAlias ( char *directory, Bool isFile,
+@@ -374,6 +375,9 @@ lexAlias(FILE *file, char **lexToken)
+ int nsize;
+ char *nbuf;
+
++ if (tokenSize >= (INT_MAX >> 2))
++ /* Stop before we overflow */
++ return EALLOC;
+ nsize = tokenSize ? (tokenSize << 1) : 64;
+ nbuf = realloc(tokenBuf, nsize);
+ if (!nbuf)
+--
+1.7.9.2
+
+From 23dcf6b1da8b5088856aef12b4a3f4581836f63a Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Fri, 25 Apr 2014 23:02:00 -0700
+Subject: [PATCH:libXfont 07/16] 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 <[email protected]>
+Signed-off-by: Alan Coopersmith <[email protected]>
+Reviewed-by: Adam Jackson <[email protected]>
+Reviewed-by: Matthieu Herrb <[email protected]>
+(cherry picked from commit 891e084b26837162b12f841060086a105edde86d)
+---
+ src/fc/fserve.c | 20 ++++++++++++++++++--
+ 1 file changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/src/fc/fserve.c b/src/fc/fserve.c
+index 92f90b2..46418bd 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;
+--
+1.7.9.2
+
+From 647d9ea15e34779afa442d362997d92488778907 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Fri, 25 Apr 2014 23:02:12 -0700
+Subject: [PATCH:libXfont 08/16] CVE-2014-0210: unvalidated lengths when
+ reading replies from font server
+
+Functions to handle replies to font server requests were casting replies
+from the generic form to reply specific structs without first checking
+that the reply was at least as long as the struct being cast to.
+
+Reported-by: Ilja Van Sprundel <[email protected]>
+Signed-off-by: Alan Coopersmith <[email protected]>
+Reviewed-by: Adam Jackson <[email protected]>
+Reviewed-by: Matthieu Herrb <[email protected]>
+(cherry picked from commit cbb64aef35960b2882be721f4b8fbaa0fb649d12)
+---
+ src/fc/fserve.c | 44 ++++++++++++++++++++++++++++++++++++++------
+ 1 file changed, 38 insertions(+), 6 deletions(-)
+
+diff --git a/src/fc/fserve.c b/src/fc/fserve.c
+index 46418bd..97b7659 100644
+--- a/src/fc/fserve.c
++++ b/src/fc/fserve.c
+@@ -91,6 +91,12 @@ in this Software without prior written authorization from The Open Group.
+ (pci)->descent || \
+ (pci)->characterWidth)
+
++/*
++ * SIZEOF(r) is in bytes, length fields in the protocol are in 32-bit words,
++ * so this converts for doing size comparisons.
++ */
++#define LENGTHOF(r) (SIZEOF(r) >> 2)
++
+ extern void ErrorF(const char *f, ...);
+
+ static int fs_read_glyphs ( FontPathElementPtr fpe, FSBlockDataPtr blockrec );
+@@ -206,9 +212,22 @@ _fs_add_rep_log (FSFpePtr conn, fsGenericReply *rep)
+ rep->sequenceNumber,
+ conn->reqbuffer[i].opcode);
+ }
++
++#define _fs_reply_failed(rep, name, op) do { \
++ if (rep) { \
++ if (rep->type == FS_Error) \
++ fprintf (stderr, "Error: %d Request: %s\n", \
++ ((fsError *)rep)->request, #name); \
++ else \
++ fprintf (stderr, "Bad Length for %s Reply: %d %s %d\n", \
++ #name, rep->length, op, LENGTHOF(name)); \
++ } \
++} while (0)
++
+ #else
+ #define _fs_add_req_log(conn,op) ((conn)->current_seq++)
+ #define _fs_add_rep_log(conn,rep)
++#define _fs_reply_failed(rep,name,op)
+ #endif
+
+ static Bool
+@@ -682,13 +701,15 @@ fs_read_open_font(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+ int ret;
+
+ rep = (fsOpenBitmapFontReply *) fs_get_reply (conn, &ret);
+- if (!rep || rep->type == FS_Error)
++ if (!rep || rep->type == FS_Error ||
++ (rep->length != LENGTHOF(fsOpenBitmapFontReply)))
+ {
+ if (ret == FSIO_BLOCK)
+ return StillWorking;
+ if (rep)
+ _fs_done_read (conn, rep->length << 2);
+ fs_cleanup_bfont (bfont);
++ _fs_reply_failed (rep, fsOpenBitmapFontReply, "!=");
+ return BadFontName;
+ }
+
+@@ -824,13 +845,15 @@ fs_read_query_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+ int ret;
+
+ rep = (fsQueryXInfoReply *) fs_get_reply (conn, &ret);
+- if (!rep || rep->type == FS_Error)
++ if (!rep || rep->type == FS_Error ||
++ (rep->length < LENGTHOF(fsQueryXInfoReply)))
+ {
+ if (ret == FSIO_BLOCK)
+ return StillWorking;
+ if (rep)
+ _fs_done_read (conn, rep->length << 2);
+ fs_cleanup_bfont (bfont);
++ _fs_reply_failed (rep, fsQueryXInfoReply, "<");
+ return BadFontName;
+ }
+
+@@ -951,13 +974,15 @@ fs_read_extent_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+ FontInfoRec *fi = &bfont->pfont->info;
+
+ rep = (fsQueryXExtents16Reply *) fs_get_reply (conn, &ret);
+- if (!rep || rep->type == FS_Error)
++ if (!rep || rep->type == FS_Error ||
++ (rep->length < LENGTHOF(fsQueryXExtents16Reply)))
+ {
+ if (ret == FSIO_BLOCK)
+ return StillWorking;
+ if (rep)
+ _fs_done_read (conn, rep->length << 2);
+ fs_cleanup_bfont (bfont);
++ _fs_reply_failed (rep, fsQueryXExtents16Reply, "<");
+ return BadFontName;
+ }
+
+@@ -1823,13 +1848,15 @@ fs_read_glyphs(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+ unsigned long minchar, maxchar;
+
+ rep = (fsQueryXBitmaps16Reply *) fs_get_reply (conn, &ret);
+- if (!rep || rep->type == FS_Error)
++ if (!rep || rep->type == FS_Error ||
++ (rep->length < LENGTHOF(fsQueryXBitmaps16Reply)))
+ {
+ if (ret == FSIO_BLOCK)
+ return StillWorking;
+ if (rep)
+ _fs_done_read (conn, rep->length << 2);
+ err = AllocError;
++ _fs_reply_failed (rep, fsQueryXBitmaps16Reply, "<");
+ goto bail;
+ }
+
+@@ -2232,12 +2259,14 @@ fs_read_list(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+ int err;
+
+ rep = (fsListFontsReply *) fs_get_reply (conn, &ret);
+- if (!rep || rep->type == FS_Error)
++ if (!rep || rep->type == FS_Error ||
++ (rep->length < LENGTHOF(fsListFontsReply)))
+ {
+ if (ret == FSIO_BLOCK)
+ return StillWorking;
+ if (rep)
+ _fs_done_read (conn, rep->length << 2);
++ _fs_reply_failed (rep, fsListFontsReply, "<");
+ return AllocError;
+ }
+ data = (char *) rep + SIZEOF (fsListFontsReply);
+@@ -2356,12 +2385,15 @@ fs_read_list_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+ _fs_free_props (&binfo->info);
+
+ rep = (fsListFontsWithXInfoReply *) fs_get_reply (conn, &ret);
+- if (!rep || rep->type == FS_Error)
++ if (!rep || rep->type == FS_Error ||
++ ((rep->nameLength != 0) &&
++ (rep->length < LENGTHOF(fsListFontsWithXInfoReply))))
+ {
+ if (ret == FSIO_BLOCK)
+ return StillWorking;
+ binfo->status = FS_LFWI_FINISHED;
+ err = AllocError;
++ _fs_reply_failed (rep, fsListFontsWithXInfoReply, "<");
+ goto done;
+ }
+ /*
+--
+1.7.9.2
+
+From 633005ac24a44dacaf6beb3ed240ae0ea7e022d7 Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <[email protected]>
+Date: Fri, 25 Apr 2014 23:02:25 -0700
+Subject: [PATCH:libXfont 09/16] CVE-2014-0211: Integer overflow in
+ fs_get_reply/_fs_start_read
+
+fs_get_reply() would take any reply size, multiply it by 4 and pass to
+_fs_start_read. If that size was bigger than the current reply buffer
+size, _fs_start_read would add it to the existing buffer size plus the
+buffer size increment constant and realloc the buffer to that result.
+
+This math could overflow, causing the code to allocate a smaller
+buffer than the amount it was about to read into that buffer from
+the network. It could also succeed, allowing the remote font server
+to cause massive allocations in the X server, possibly using up all
+the address space in a 32-bit X server, allowing the triggering of
+other bugs in code that fails to handle malloc failure properly.
+
+This patch protects against both problems, by disconnecting any
+font server trying to feed us more than (the somewhat arbitrary)
+64 mb in a single reply.
+
+Signed-off-by: Alan Coopersmith <[email protected]>
+Reviewed-by: Adam Jackson <[email protected]>
+Reviewed-by: Matthieu Herrb <[email protected]>
+(cherry picked from commit 0f1a5d372c143f91a602bdf10c917d7eabaee09b)
+---
+ src/fc/fserve.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/src/fc/fserve.c b/src/fc/fserve.c
+index 97b7659..bfd7dbe 100644
+--- a/src/fc/fserve.c
++++ b/src/fc/fserve.c
+@@ -97,6 +97,9 @@ in this Software without prior written authorization from The Open Group.
+ */
+ #define LENGTHOF(r) (SIZEOF(r) >> 2)
+
++/* Somewhat arbitrary limit on maximum reply size we'll try to read. */
++#define MAX_REPLY_LENGTH ((64 * 1024 * 1024) >> 2)
++
+ extern void ErrorF(const char *f, ...);
+
+ static int fs_read_glyphs ( FontPathElementPtr fpe, FSBlockDataPtr blockrec );
+@@ -619,6 +622,21 @@ fs_get_reply (FSFpePtr conn, int *error)
+
+ rep = (fsGenericReply *) buf;
+
++ /*
++ * Refuse to accept replies longer than a maximum reasonable length,
++ * before we pass to _fs_start_read, since it will try to resize the
++ * incoming connection buffer to this size. Also avoids integer overflow
++ * on 32-bit systems.
++ */
++ if (rep->length > MAX_REPLY_LENGTH)
++ {
++ ErrorF("fserve: reply length %d > MAX_REPLY_LENGTH, disconnecting"
++ " from font server\n", rep->length);
++ _fs_connection_died (conn);
++ *error = FSIO_ERROR;
++ return 0;
++ }
++
+ ret = _fs_start_read (conn, rep->length << 2, &buf);
+ if (ret != FSIO_READY)
+ {
+--
+1.7.9.2
+