[packages/xorg-lib-libXfont] Rel 3. Fixes: CVE-2026-56001, CVE-2026-56002, CVE-2026-56003, CVE-2026-59679, CVE-2026-44950
arekm
arekm at pld-linux.org
Sun Oct 18 12:21:28 CEST 2026
commit 990b60679e8e8da47802580215703643f5637d73
Author: Arkadiusz Miśkiewicz <arekm at maven.pl>
Date: Sun Oct 18 12:20:58 2026 +0200
Rel 3. Fixes: CVE-2026-56001, CVE-2026-56002, CVE-2026-56003, CVE-2026-59679, CVE-2026-44950
CVE-2026-44950.patch | 92 ++++++++++++++++++++++++++++++++
CVE-2026-56001.patch | 82 ++++++++++++++++++++++++++++
CVE-2026-56002.patch | 142 +++++++++++++++++++++++++++++++++++++++++++++++++
CVE-2026-56003.patch | 110 ++++++++++++++++++++++++++++++++++++++
CVE-2026-59679.patch | 89 +++++++++++++++++++++++++++++++
xorg-lib-libXfont.spec | 19 ++++---
6 files changed, 528 insertions(+), 6 deletions(-)
---
diff --git a/xorg-lib-libXfont.spec b/xorg-lib-libXfont.spec
index 61fbad7..228edae 100644
--- a/xorg-lib-libXfont.spec
+++ b/xorg-lib-libXfont.spec
@@ -2,11 +2,16 @@ Summary: X font library used by the X server
Summary(pl.UTF-8): Używana przez X serwer biblioteka fontów X
Name: xorg-lib-libXfont
Version: 1.5.4
-Release: 2
+Release: 3
License: MIT
Group: X11/Libraries
Source0: https://xorg.freedesktop.org/releases/individual/lib/libXfont-%{version}.tar.bz2
# Source0-md5: 16eaf156edd79b68038b6a7c44aa9e9b
+Patch0: CVE-2026-56001.patch
+Patch1: CVE-2026-56002.patch
+Patch2: CVE-2026-56003.patch
+Patch3: CVE-2026-59679.patch
+Patch4: CVE-2026-44950.patch
URL: https://xorg.freedesktop.org/
BuildRequires: autoconf >= 2.60
BuildRequires: automake
@@ -51,10 +56,7 @@ Group: X11/Development/Libraries
Requires: %{name} = %{version}-%{release}
Requires: bzip2-devel
Requires: freetype-devel >= 2
-Requires: xorg-lib-libfontenc-devel
-Requires: xorg-lib-xtrans-devel
Requires: xorg-proto-fontsproto-devel >= 2.1.3
-Requires: xorg-proto-xproto-devel
Requires: zlib-devel
Obsoletes: libXfont-devel
@@ -89,6 +91,11 @@ Pakiet zawiera statyczną bibliotekę libXfont.
%prep
%setup -q -n libXfont-%{version}
+%patch -P0 -p1
+%patch -P1 -p1
+%patch -P2 -p1
+%patch -P3 -p1
+%patch -P4 -p1
%build
%{__libtoolize}
@@ -119,12 +126,12 @@ rm -rf $RPM_BUILD_ROOT
%defattr(644,root,root,755)
%doc AUTHORS COPYING ChangeLog README
%attr(755,root,root) %{_libdir}/libXfont.so.*.*.*
-%attr(755,root,root) %ghost %{_libdir}/libXfont.so.1
+%ghost %{_libdir}/libXfont.so.1
%files devel
%defattr(644,root,root,755)
%doc doc/*.html
-%attr(755,root,root) %{_libdir}/libXfont.so
+%{_libdir}/libXfont.so
%{_includedir}/X11/fonts/bdfint.h
%{_includedir}/X11/fonts/bitmap.h
%{_includedir}/X11/fonts/bufio.h
diff --git a/CVE-2026-44950.patch b/CVE-2026-44950.patch
new file mode 100644
index 0000000..5c3eb24
--- /dev/null
+++ b/CVE-2026-44950.patch
@@ -0,0 +1,92 @@
+From c2d222bb22c623d8a40f3275077fc7e6617f2c8a Mon Sep 17 00:00:00 2001
+From: Peter Hutterer <peter.hutterer at who-t.net>
+Date: Mon, 13 Jul 2026 15:50:09 +1000
+Subject: [PATCH] fserve: bounds-check cumulative glyph data writes in
+ fs_read_glyphs
+
+fs_read_glyphs() copies each glyph's bitmap into a single allbits
+buffer allocated to rep->nbytes bytes. The per-glyph guard validates
+only that the source slice (position, length) lies within the pbitmaps
+source buffer. It does not check whether the running destination cursor
+has exceeded the allocation.
+
+A malicious font server can send overlapping source offsets (e.g. 1000
+glyphs each referencing {position:0, length:64} with nbytes=64). Each
+individual source range passes validation, but the cumulative writes
+total 64000 bytes into a 64-byte destination buffer.
+
+Interestingly there was an unconditional debug printf in place that
+sort-of warned about this but didn't prevent this. Let's remove that and
+instead use the actual check to bail out before we run OOB.
+
+A regression test is included that sends 100 glyphs each referencing
+the same 64-byte source slice into a 64-byte destination buffer, and
+verifies the library rejects the overflow.
+
+CVE-2026-44950
+
+Found-by: Zhixi "Jace" Sun, independent security researcher
+Assisted-by: Claude:claude-opus-4-6
+Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
+Part-of: <https://gitlab.freedesktop.org/xorg/lib/libxfont/-/merge_requests/36>
+---
+ src/fc/fserve.c | 23 +++++++++------
+ test/test-fserve-read-glyphs.c | 52 +++++++++++++++++++++++++++++++---
+ 2 files changed, 62 insertions(+), 13 deletions(-)
+
+diff --git a/src/fc/fserve.c b/src/fc/fserve.c
+index 744a68c..3e479a9 100644
+--- a/src/fc/fserve.c
++++ b/src/fc/fserve.c
+@@ -1900,10 +1900,7 @@ fs_read_glyphs(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+ fsOffset32 local_off;
+ char *off_adr;
+ pointer pbitmaps;
+- char *bits, *allbits;
+-#ifdef DEBUG
+- char *origallbits;
+-#endif
++ char *bits, *allbits, *origallbits;
+ int i,
+ err;
+ int nranges = 0;
+@@ -2004,8 +2001,8 @@ fs_read_glyphs(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+ goto bail;
+ }
+
+-#ifdef DEBUG
+ origallbits = allbits;
++#ifdef DEBUG
+ fprintf (stderr, "Reading %d glyphs in %d bytes for %s\n",
+ (int) rep->num_chars, (int) rep->nbytes, fsd->name);
+ #endif
+@@ -2036,6 +2033,18 @@ fs_read_glyphs(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+ (local_off.position < rep->nbytes) &&
+ (local_off.length <= (rep->nbytes - local_off.position)))
+ {
++ /* Check that the destination buffer has enough room
++ for this glyph to prevent a heap overflow from
++ overlapping source offsets. */
++ if (local_off.length >
++ rep->nbytes - (allbits - origallbits))
++ {
++ ErrorF("fserve: glyph data overflow: "
++ "cumulative write exceeds nbytes (%u)\n",
++ (unsigned) rep->nbytes);
++ err = AllocError;
++ goto bail;
++ }
+ bits = allbits;
+ allbits += local_off.length;
+ memcpy(bits, (char *)pbitmaps + local_off.position,
+@@ -2063,10 +2072,6 @@ fs_read_glyphs(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+ }
+ off_adr += SIZEOF(fsOffset32);
+ }
+-#ifdef DEBUG
+- fprintf (stderr, "Used %d bytes instead of %d\n",
+- (int) (allbits - origallbits), (int) rep->nbytes);
+-#endif
+
+ if (blockrec->type == FS_OPEN_FONT)
+ {
diff --git a/CVE-2026-56001.patch b/CVE-2026-56001.patch
new file mode 100644
index 0000000..c7cbee2
--- /dev/null
+++ b/CVE-2026-56001.patch
@@ -0,0 +1,82 @@
+From be0b08e2d354138d3222b4490e2a77c6ee42f778 Mon Sep 17 00:00:00 2001
+From: Peter Hutterer <peter.hutterer at who-t.net>
+Date: Mon, 1 Jun 2026 16:46:10 +1000
+Subject: [PATCH] bitscale: fix integer overflow in BitmapScaleBitmaps
+ bytestoalloc
+
+bytestoalloc is declared as unsigned int (32-bit). When the sum of
+per-glyph byte counts exceeds 2^32, the value wraps around and calloc()
+allocates a buffer that is too small. The subsequent ScaleBitmap loop
+then writes past the end of the allocated buffer.
+
+Change bytestoalloc from unsigned int to size_t to match the actual
+allocation size type, and add an explicit overflow check in the
+accumulation loop to bail out if the total would exceed SIZE_MAX.
+
+This vulnerability was discovered by:
+Anonymous working with TrendAI Zero Day Initiative
+
+CVE-2026-56001/ZDI-CAN-30558
+
+Assisted-by: Claude:claude-opus-4-6
+Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
+Part-of: <https://gitlab.freedesktop.org/xorg/lib/libxfont/-/merge_requests/34>
+---
+ src/bitmap/bitscale.c | 25 +++++++++++++++++++++-----
+ 1 file changed, 21 insertions(+), 4 deletions(-)
+
+diff --git a/src/bitmap/bitscale.c b/src/bitmap/bitscale.c
+index 3f3c10e..5f465d1 100644
+--- a/src/bitmap/bitscale.c
++++ b/src/bitmap/bitscale.c
+@@ -38,6 +38,7 @@
+ #include <X11/fonts/bitmap.h>
+ #include <X11/fonts/fontutil.h>
+ #include <math.h>
++#include <stdint.h>
+
+ #ifndef MAX
+ #define MAX(a,b) (((a)>(b)) ? a : b)
+@@ -1456,7 +1456,7 @@ BitmapScaleBitmaps(FontPtr pf, /* scaled font */
+ opci;
+ FontInfoPtr pfi;
+ int glyph;
+- unsigned bytestoalloc = 0;
++ size_t bytestoalloc = 0;
+ int firstCol, lastCol, firstRow, lastRow;
+
+ double xform[4], inv_xform[4];
+@@ -1483,8 +1483,25 @@ BitmapScaleBitmaps(FontPtr pf, /* scaled font */
+ glyph = pf->glyph;
+ for (i = 0; i < nchars; i++)
+ {
+- if ((pci = ACCESSENCODING(bitmapFont->encoding, i)))
+- bytestoalloc += BYTES_FOR_GLYPH(pci, glyph);
++ if ((pci = ACCESSENCODING(bitmapFont->encoding, i))) {
++ size_t glyphsize = BYTES_FOR_GLYPH(pci, glyph);
++ if (bytestoalloc > SIZE_MAX - glyphsize) {
++ fprintf(stderr,
++ "Error: bitmap allocation overflow for scaled font\n");
++ goto bail;
++ }
++ bytestoalloc += glyphsize;
++ }
++ }
++
++ /* Reject unreasonably large bitmap allocations that could result
++ * from malicious fonts with extreme scale factors. 256 MiB is
++ * far beyond any legitimate scaled bitmap font. */
++#define BITMAP_SCALE_MAX_ALLOC (256 * 1024 * 1024)
++ if (bytestoalloc > BITMAP_SCALE_MAX_ALLOC) {
++ fprintf(stderr,
++ "Error: scaled bitmap size %zu exceeds limit\n", bytestoalloc);
++ goto bail;
+ }
+
+ /* Do we add the font malloc stuff for VALUE ADDED ? */
+@@ -1517 +1534 @@ BitmapScaleBitmaps(FontPtr pf, /* scaled font */
+- fprintf(stderr, "Error: Couldn't allocate bitmaps (%d)\n", bytestoalloc);
++ fprintf(stderr, "Error: Couldn't allocate bitmaps (%zu)\n", bytestoalloc);
+--
+GitLab
+
diff --git a/CVE-2026-56002.patch b/CVE-2026-56002.patch
new file mode 100644
index 0000000..68c7b8d
--- /dev/null
+++ b/CVE-2026-56002.patch
@@ -0,0 +1,142 @@
+From b4389e0b1d84a690b819bb27b1439968811a3674 Mon Sep 17 00:00:00 2001
+From: Peter Hutterer <peter.hutterer at who-t.net>
+Date: Mon, 1 Jun 2026 16:48:40 +1000
+Subject: [PATCH] pcfread: validate bitmap sizes and offsets against per-glyph
+ metrics
+
+pcfReadFont() uses bitmapSizes[] read directly from the PCF file to
+allocate the repadded bitmap buffer. However, per-glyph metrics (also
+from the file) control how much data RepadBitmap() writes. A malicious
+PCF font can declare a small bitmapSizes[] value while having per-glyph
+metrics that require more space, causing a heap buffer overflow.
+
+A similar issue happens with the encoding offsets: pcfReadFont reads
+encoding offsets from the PCF file and uses them to index into the
+metrics array without bounds checking. A crafted font can set an
+encoding offset larger than nmetrics, causing an out-of-bounds pointer
+that is later dereferenced when glyphs are accessed through the encoding
+table.
+
+And the no-repad bitmap path (when PCF_GLYPH_PAD matches the requested
+glyph pad) only validated that each glyph's offset was within the bitmap
+buffer, but did not check that the full glyph extent (offset +
+BYTES_PER_ROW * height) fits within the buffer. A crafted font with a
+glyph offset near the end of a small bitmap buffer but large glyph
+metrics causes a heap buffer over-read when the glyph is later rendered.
+
+This vulnerability was discovered by:
+ Anonymous working with TrendAI Zero Day Initiative
+
+CVE-2026-56002/ZDI-CAN-30559
+
+Assisted-by: Claude:claude-opus-4-6
+Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
+Part-of: <https://gitlab.freedesktop.org/xorg/lib/libxfont/-/merge_requests/34>
+---
+ src/bitmap/pcfread.c | 59 +++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 56 insertions(+), 3 deletions(-)
+
+diff --git a/src/bitmap/pcfread.c b/src/bitmap/pcfread.c
+index 7c2e7e1..a385331 100644
+--- a/src/bitmap/pcfread.c
++++ b/src/bitmap/pcfread.c
+@@ -43,6 +43,7 @@
+ #endif
+
+ #include <stdarg.h>
++#include <limits.h>
+ #include <stdint.h>
+ #include <string.h>
+
+@@ -532,25 +532,74 @@ pcfReadFont(FontPtr pFont, FontFilePtr file,
+ int old,
+ new;
+ xCharInfo *metric;
++ int srcPad = PCF_GLYPH_PAD(format);
+
+- sizepadbitmaps = bitmapSizes[PCF_SIZE_TO_INDEX(glyph)];
+- padbitmaps = malloc(sizepadbitmaps);
++ /* Compute the actual required size from per-glyph metrics instead
++ * of trusting the file's bitmapSizes[] value, which may be smaller
++ * than the actual data written by RepadBitmap. */
++ sizepadbitmaps = 0;
++ for (i = 0; i < nbitmaps; i++) {
++ int w, h, glyphBytes;
++ metric = &metrics[i].metrics;
++ w = metric->rightSideBearing - metric->leftSideBearing;
++ h = metric->ascent + metric->descent;
++ glyphBytes = BYTES_PER_ROW(w, glyph) * h;
++ if (glyphBytes < 0 || (glyphBytes > 0 && sizepadbitmaps > INT_MAX - glyphBytes)) {
++ pcfError("pcfReadFont(): bitmap size overflow\n");
++ goto Bail;
++ }
++ sizepadbitmaps += glyphBytes;
++ }
++ padbitmaps = malloc(sizepadbitmaps ? sizepadbitmaps : 1);
+ if (!padbitmaps) {
+ pcfError("pcfReadFont(): Couldn't allocate padbitmaps (%d)\n", sizepadbitmaps);
+ goto Bail;
+ }
+ new = 0;
+ for (i = 0; i < nbitmaps; i++) {
++ int srcGlyphBytes;
++
+ old = offsets[i];
+ metric = &metrics[i].metrics;
++
++ /* Validate source offset and source glyph size against the
++ * source bitmap buffer to prevent out-of-bounds reads. */
++ srcGlyphBytes = BYTES_PER_ROW(
++ metric->rightSideBearing - metric->leftSideBearing,
++ srcPad) * (metric->ascent + metric->descent);
++ if (old < 0 || old > sizebitmaps ||
++ srcGlyphBytes < 0 || srcGlyphBytes > sizebitmaps - old) {
++ pcfError("pcfReadFont(): bitmap offset/size out of bounds\n");
++ free(padbitmaps);
++ goto Bail;
++ }
++
+ offsets[i] = new;
+ new += RepadBitmap(bitmaps + old, padbitmaps + new,
+- PCF_GLYPH_PAD(format), glyph,
++ srcPad, glyph,
+ metric->rightSideBearing - metric->leftSideBearing,
+ metric->ascent + metric->descent);
+ }
+ free(bitmaps);
+ bitmaps = padbitmaps;
++ } else {
++ /* Validate offsets and full glyph extents against bitmap buffer */
++ for (i = 0; i < nbitmaps; i++) {
++ int glyphBytes;
++ xCharInfo *metric = &metrics[i].metrics;
++
++ glyphBytes = BYTES_PER_ROW(
++ metric->rightSideBearing - metric->leftSideBearing,
++ glyph) * (metric->ascent + metric->descent);
++ if (offsets[i] >= (CARD32)sizebitmaps ||
++ glyphBytes < 0 ||
++ glyphBytes > sizebitmaps - (int)offsets[i]) {
++ pcfError("pcfReadFont(): bitmap offset/size out of bounds "
++ "(offset %u, size %d, total %d)\n",
++ offsets[i], glyphBytes, sizebitmaps);
++ goto Bail;
++ }
++ }
+ }
+ for (i = 0; i < nbitmaps; i++)
+ metrics[i].bits = bitmaps + offsets[i];
+@@ -625,6 +674,10 @@ pcfReadFont(FontPtr pFont, FontFilePtr file,
+ if (IS_EOF(file)) goto Bail;
+ if (encodingOffset == 0xFFFF) {
+ pFont->info.allExist = FALSE;
++ } else if (encodingOffset >= nmetrics) {
++ pcfError("pcfReadFont(): encoding offset %d out of range (nmetrics=%d)\n",
++ encodingOffset, nmetrics);
++ goto Bail;
+ } else {
+ if(!encoding[SEGMENT_MAJOR(i)]) {
+ encoding[SEGMENT_MAJOR(i)]=
+--
+GitLab
+
diff --git a/CVE-2026-56003.patch b/CVE-2026-56003.patch
new file mode 100644
index 0000000..139002d
--- /dev/null
+++ b/CVE-2026-56003.patch
@@ -0,0 +1,110 @@
+From dff957a5158da038a282a59a31fe736702732939 Mon Sep 17 00:00:00 2001
+From: Peter Hutterer <peter.hutterer at who-t.net>
+Date: Mon, 1 Jun 2026 16:49:55 +1000
+Subject: [PATCH] bitscale: add bounds check to computeProps for property
+ buffer
+
+ComputeScaledProperties allocates a fixed-size property buffer of 70
+slots. computeProps iterates the source font's properties and writes 1
+slot for unscaled properties or 2 slots for scaledX/scaledY properties,
+with no bounds check. A malicious font with many duplicate properties
+matching fontPropTable entries can overflow the allocated buffer.
+
+Fix this by passing the remaining buffer capacity to computeProps and
+checking it before each write. Properties that would exceed the buffer
+are silently skipped.
+
+The function is also restructured to handle the buffer writes for
+scaledX/scaledY inside the switch cases directly, rather than in a
+separate block after the switch. This makes the control flow clearer and
+ensures the bounds check covers all writes.
+
+This vulnerability was discovered by:
+Anonymous working with TrendAI Zero Day Initiative
+
+CVE-2026-56003/ZDI-CAN-30560
+
+Assisted-by: Claude:claude-opus-4-6
+Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
+Part-of: <https://gitlab.freedesktop.org/xorg/lib/libxfont/-/merge_requests/34>
+---
+ src/bitmap/bitscale.c | 39 ++++++++++++++++++++-------------------
+ 1 file changed, 20 insertions(+), 19 deletions(-)
+
+diff --git a/src/bitmap/bitscale.c b/src/bitmap/bitscale.c
+index 5f465d1..ec57f55 100644
+--- a/src/bitmap/bitscale.c
++++ b/src/bitmap/bitscale.c
+@@ -507,7 +507,8 @@ static int
+ computeProps(FontPropPtr pf, char *wasStringProp,
+ FontPropPtr npf, char *isStringProp,
+ unsigned int nprops, double xfactor, double yfactor,
+- double sXfactor, double sYfactor)
++ double sXfactor, double sYfactor,
++ int maxprops)
+ {
+ int n;
+ int count;
+@@ -522,14 +523,26 @@ computeProps(FontPropPtr pf, char *wasStringProp,
+
+ switch (t->type) {
+ case scaledX:
+- npf->value = doround(xfactor * (double)pf->value);
+- rawfactor = sXfactor;
+- break;
+ case scaledY:
+- npf->value = doround(yfactor * (double)pf->value);
+- rawfactor = sYfactor;
++ if (count + 2 > maxprops)
++ continue;
++ npf->value = (t->type == scaledX)
++ ? doround(xfactor * (double)pf->value)
++ : doround(yfactor * (double)pf->value);
++ rawfactor = (t->type == scaledX) ? sXfactor : sYfactor;
++ npf->name = pf->name;
++ npf++;
++ count++;
++ npf->value = doround(rawfactor * (double)pf->value);
++ npf->name = rawFontPropTable[t - fontPropTable].atom;
++ npf++;
++ count++;
++ *isStringProp++ = *wasStringProp;
++ *isStringProp++ = *wasStringProp;
+ break;
+ case unscaled:
++ if (count + 1 > maxprops)
++ continue;
+ npf->value = pf->value;
+ npf->name = pf->name;
+ npf++;
+@@ -539,18 +552,6 @@ computeProps(FontPropPtr pf, char *wasStringProp,
+ default:
+ break;
+ }
+- if (t->type != unscaled)
+- {
+- npf->name = pf->name;
+- npf++;
+- count++;
+- npf->value = doround(rawfactor * (double)pf->value);
+- npf->name = rawFontPropTable[t - fontPropTable].atom;
+- npf++;
+- count++;
+- *isStringProp++ = *wasStringProp;
+- *isStringProp++ = *wasStringProp;
+- }
+ }
+ return count;
+ }
+@@ -667,7 +668,7 @@ ComputeScaledProperties(FontInfoPtr sourceFontInfo, /* the font to be scaled */
+ n = NPROPS;
+ n += computeProps(sourceFontInfo->props, sourceFontInfo->isStringProp,
+ fp, isStringProp, sourceFontInfo->nprops, dx, dy,
+- sdx, sdy);
++ sdx, sdy, nProps - NPROPS);
+ return n;
+ }
+
+--
+GitLab
+
diff --git a/CVE-2026-59679.patch b/CVE-2026-59679.patch
new file mode 100644
index 0000000..2f7b0d5
--- /dev/null
+++ b/CVE-2026-59679.patch
@@ -0,0 +1,89 @@
+From 668fea81f40bcb48ec67fb55d0b851049d265290 Mon Sep 17 00:00:00 2001
+From: Peter Hutterer <peter.hutterer at who-t.net>
+Date: Mon, 13 Jul 2026 15:48:06 +1000
+Subject: [PATCH] fserve: validate num_chars against encoding array size in
+ fs_read_glyphs
+
+FS_QueryXExtents16 causes us to allocate the encoding[] array, later
+during the FS_QueryXBitmaps16 reply handling we fill in that array.
+There is no verification that the allocation is large enough, a
+malicious font server could send us a small numExtents and a
+large num_chars to force underallocation and OOB read/rwrite.
+
+A regression test is included that constructs a crafted
+FS_QueryXBitmaps16 reply with num_chars > num_encoding and verifies
+the library rejects it.
+
+CVE-2026-59679
+
+Found-by: Zhixi "Jace" Sun, independent security researcher
+Assisted-by: Claude:claude-opus-4-6
+Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
+Part-of: <https://gitlab.freedesktop.org/xorg/lib/libxfont/-/merge_requests/36>
+---
+ Makefile.am | 20 +-
+ src/fc/fserve.c | 22 ++
+ src/fc/fservestr.h | 1 +
+ test/test-fserve-read-glyphs.c | 368 +++++++++++++++++++++++++++++++++
+ 4 files changed, 409 insertions(+), 2 deletions(-)
+ create mode 100644 test/test-fserve-read-glyphs.c
+
+diff --git a/src/fc/fserve.c b/src/fc/fserve.c
+index abf7d07..744a68c 100644
+--- a/src/fc/fserve.c
++++ b/src/fc/fserve.c
+@@ -1081,6 +1081,7 @@ fs_read_extent_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+ return AllocError;
+ }
+ fsfont->encoding = pCI;
++ fsfont->num_encoding = numExtents;
+ if (haveInk)
+ fsfont->inkMetrics = pCI + numExtents;
+ else
+@@ -1980,6 +1981,17 @@ fs_read_glyphs(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+ {
+ minchar = 0;
+ maxchar = rep->num_chars;
++
++ /* Reject replies where num_chars exceeds the encoding array
++ size allocated in fs_read_extent_info() to prevent
++ out-of-bounds access on encoding[]. */
++ if (rep->num_chars > (CARD32)fsdata->num_encoding)
++ {
++ ErrorF("fserve: num_chars (%u) > num_encoding (%d)\n",
++ (unsigned) rep->num_chars, fsdata->num_encoding);
++ err = AllocError;
++ goto bail;
++ }
+ }
+
+ off_adr = (char *)ppbits;
+@@ -2001,6 +2013,16 @@ fs_read_glyphs(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+ for (i = 0; i < rep->num_chars; i++)
+ {
+ memcpy(&local_off, off_adr, SIZEOF(fsOffset32)); /* align it */
++ /* Bounds-check minchar against the encoding array size to
++ prevent out-of-bounds access from a malicious font server
++ reply with more num_chars than num_extents. */
++ if (minchar >= (unsigned long)fsdata->num_encoding)
++ {
++ ErrorF("fserve: glyph index %lu >= num_encoding (%d)\n",
++ minchar, fsdata->num_encoding);
++ err = AllocError;
++ goto bail;
++ }
+ if (blockrec->type == FS_OPEN_FONT ||
+ fsdata->encoding[minchar].bits == &_fs_glyph_requested)
+ {
+diff --git a/src/fc/fservestr.h b/src/fc/fservestr.h
+index 29ae46e..da95e41 100644
+--- a/src/fc/fservestr.h
++++ b/src/fc/fservestr.h
+@@ -43,6 +43,7 @@ typedef struct _fs_glyph {
+ typedef struct _fs_font {
+ CharInfoPtr pDefault;
+ CharInfoPtr encoding;
++ int num_encoding;
+ CharInfoPtr inkMetrics;
+ FSGlyphPtr glyphs;
+ } FSFontRec, *FSFontPtr;
================================================================
---- gitweb:
http://git.pld-linux.org/gitweb.cgi/packages/xorg-lib-libXfont.git/commitdiff/990b60679e8e8da47802580215703643f5637d73
More information about the pld-cvs-commit
mailing list