1
From b6002903efd840672d070d317911c675c2d23c1c Mon Sep 17 00:00:00 2001
2
From: Alan Coopersmith <alan.coopersmith@oracle.com>
3
Date: Fri, 25 Apr 2014 23:03:24 -0700
4
Subject: [PATCH:libXfont 10/12] CVE-2014-XXXB: unvalidated length fields in
7
fs_read_glyphs() parses a reply from the font server. The reply
8
contains embedded length fields, none of which are validated.
9
This can cause out of bound reads when looping over the glyph
12
Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
13
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
14
Reviewed-by: Adam Jackson <ajax@redhat.com>
15
Reviewed-by: Matthieu Herrb <matthieu@herrb.eu>
17
src/fc/fserve.c | 29 ++++++++++++++++++++++++++++-
18
1 file changed, 28 insertions(+), 1 deletion(-)
20
Index: libxfont/src/fc/fserve.c
21
===================================================================
22
--- libxfont.orig/src/fc/fserve.c
23
+++ libxfont/src/fc/fserve.c
24
@@ -1909,6 +1909,7 @@ fs_read_glyphs(FontPathElementPtr fpe, F
25
FontInfoPtr pfi = &pfont->info;
26
fsQueryXBitmaps16Reply *rep;
28
+ long bufleft; /* length of reply left to use */
32
@@ -1940,9 +1941,33 @@ fs_read_glyphs(FontPathElementPtr fpe, F
34
buf += SIZEOF (fsQueryXBitmaps16Reply);
36
+ bufleft = rep->length << 2;
37
+ bufleft -= SIZEOF (fsQueryXBitmaps16Reply);
39
+ if ((bufleft / SIZEOF (fsOffset32)) < rep->num_chars)
43
+ "fsQueryXBitmaps16: num_chars (%d) > bufleft (%ld) / %d\n",
44
+ rep->num_chars, bufleft, SIZEOF (fsOffset32));
49
ppbits = (fsOffset32 *) buf;
50
buf += SIZEOF (fsOffset32) * (rep->num_chars);
51
+ bufleft -= SIZEOF (fsOffset32) * (rep->num_chars);
53
+ if (bufleft < rep->nbytes)
57
+ "fsQueryXBitmaps16: nbytes (%d) > bufleft (%ld)\n",
58
+ rep->nbytes, bufleft);
63
pbitmaps = (pointer ) buf;
65
if (blockrec->type == FS_LOAD_GLYPHS)
66
@@ -2000,7 +2025,9 @@ fs_read_glyphs(FontPathElementPtr fpe, F
68
if (NONZEROMETRICS(&fsdata->encoding[minchar].metrics))
70
- if (local_off.length)
71
+ if (local_off.length &&
72
+ (local_off.position < rep->nbytes) &&
73
+ (local_off.length <= (rep->nbytes - local_off.position)))
76
allbits += local_off.length;