Fix CVE-2026-59679: validate num_chars in fs_read_glyphs

Backport upstream commit 668fea81 to fix CVE-2026-59679, an
out-of-bounds read/write vulnerability in fs_read_glyphs().
The fix validates that num_chars from the FS_QueryXBitmaps16
reply does not exceed the encoding array size allocated during
FS_QueryXExtents16 handling, preventing exploitation by a
malicious font server. A regression test is included.

CVE: CVE-2026-59679
Upstream patches:
 - 668fea81f4.patch
Resolves: RHEL-221956

This commit was backported by Ymir, a Red Hat Enterprise Linux software maintenance AI agent.

Assisted-by: Ymir
This commit is contained in:
RHEL Packaging Agent 2026-08-06 10:55:27 +00:00
parent 7505ca59ac
commit 651c992437
2 changed files with 124 additions and 1 deletions

View File

@ -0,0 +1,117 @@
From 76a453c43a7fb74f1e6258d452b3d3df51b97af4 Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@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@who-t.net>
Part-of: <https://gitlab.freedesktop.org/xorg/lib/libxfont/-/merge_requests/36>
---
Makefile.am | 16 ++++++++++++++++
src/fc/fserve.c | 22 ++++++++++++++++++++++
src/fc/fservestr.h | 1 +
3 files changed, 39 insertions(+)
diff --git a/Makefile.am b/Makefile.am
index c1a3db2..ef9bc40 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -157,6 +157,22 @@ endif
EXTRA_DIST = src/builtins/buildfont
+# Security regression tests
+TESTS =
+check_PROGRAMS =
+
+if XFONT_FC
+TESTS += test-fserve-read-glyphs
+check_PROGRAMS += test-fserve-read-glyphs
+
+# The test #includes fserve.c directly to access static functions so
+# we statically link against libXfont2.a.
+test_fserve_read_glyphs_SOURCES = test/test-fserve-read-glyphs.c
+test_fserve_read_glyphs_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/include -I$(top_srcdir)/src/fc
+test_fserve_read_glyphs_LDFLAGS = -static
+test_fserve_read_glyphs_LDADD = libXfont2.la $(LTLIBOBJS)
+endif XFONT_FC
+
MAINTAINERCLEANFILES = ChangeLog INSTALL
.PHONY: ChangeLog INSTALL
diff --git a/src/fc/fserve.c b/src/fc/fserve.c
index 708fc35..4141c3c 100644
--- a/src/fc/fserve.c
+++ b/src/fc/fserve.c
@@ -1097,6 +1097,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
@@ -2004,6 +2005,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;
@@ -2025,6 +2037,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;
--
2.39.5

View File

@ -1,7 +1,7 @@
Summary: X.Org X11 libXfont2 runtime library
Name: libXfont2
Version: 2.0.3
Release: 2%{?dist}.2
Release: 2%{?dist}.3
License: MIT
Group: System Environment/Libraries
URL: http://www.x.org
@ -21,6 +21,8 @@ Patch3: 0003-bitscale-add-bounds-check-to-computeProps-for-proper.patch
# https://gitlab.freedesktop.org/xorg/lib/libxfont/-/commit/c2d222bb22c623d8a40f3275077fc7e6617f2c8a
Patch4: libXfont2-2.0.3-CVE-2026-44950.patch
# https://gitlab.freedesktop.org/xorg/lib/libxfont/-/commit/668fea81f40bcb48ec67fb55d0b851049d265290
Patch5: 0004-fserve-validate-num_chars-against-encoding-array-siz.patch
%description
X.Org X11 libXfont2 runtime library
@ -63,6 +65,10 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
%{_libdir}/pkgconfig/xfont2.pc
%changelog
* Thu Aug 06 2026 RHEL Packaging Agent <redhat-ymir-agent@redhat.com> - 2.0.3-2.3
- CVE fix for: CVE-2026-59679
Resolves: https://redhat.atlassian.net/browse/RHEL-221956
* Thu Aug 06 2026 RHEL Packaging Agent <redhat-ymir-agent@redhat.com> - 2.0.3-2.2
- CVE fix for: CVE-2026-44950
Resolves: https://redhat.atlassian.net/browse/RHEL-222015