CVE fix for CVE-2026-55999

Resolves: https://redhat.atlassian.net/browse/RHEL-191504
This commit is contained in:
Michel Dänzer 2026-07-09 16:33:45 +02:00 committed by Michel Dänzer
parent 1152258edf
commit 399d39a8ae
2 changed files with 186 additions and 1 deletions

179
CVE-2026-55999.patch Normal file
View File

@ -0,0 +1,179 @@
From 0f1f4bcbfb1f23b800dfe386782d3a0f05b6756f Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Mon, 1 Jun 2026 20:44:34 +1000
Subject: [PATCH xserver 1/2] fb/mi/glamor: reject glyphs with negative
dimensions
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
GLYPHWIDTHPIXELS and GLYPHHEIGHTPIXELS compute glyph dimensions from
signed INT16 fields. A crafted PCF font can produce negative results
(e.g. rightSideBearing < leftSideBearing).
All callees have a while (height--) loop which will end up in OOB writes
for negative height values.
In the case of a negative height, some callees cast to size_t or end up
with negative strides.
The same pattern exists in fbPoloyGlyphBit, miPolyGlyphBlt and
glamor_poly_glyph_blt_gl, so let's fix all of them in one go.
Assisted-by: Claude:claude-opus-4-6
(cherry picked from commit e31efd3e106e53bfc29d499ff0a34b0d20013f2d)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2252>
---
fb/fbglyph.c | 4 ++--
glamor/glamor_glyphblt.c | 2 +-
mi/miglblt.c | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/fb/fbglyph.c b/fb/fbglyph.c
index 1bdc2d4fd..5c9318f5e 100644
--- a/fb/fbglyph.c
+++ b/fb/fbglyph.c
@@ -95,7 +95,7 @@ fbPolyGlyphBlt(DrawablePtr pDrawable,
pglyph = FONTGLYPHBITS(pglyphBase, pci);
gWidth = GLYPHWIDTHPIXELS(pci);
gHeight = GLYPHHEIGHTPIXELS(pci);
- if (gWidth && gHeight) {
+ if (gWidth > 0 && gHeight > 0) {
gx = x + pci->metrics.leftSideBearing;
gy = y - pci->metrics.ascent;
if (glyph && gWidth <= sizeof(FbStip) * 8 &&
@@ -197,7 +197,7 @@ fbImageGlyphBlt(DrawablePtr pDrawable,
pglyph = FONTGLYPHBITS(pglyphBase, pci);
gWidth = GLYPHWIDTHPIXELS(pci);
gHeight = GLYPHHEIGHTPIXELS(pci);
- if (gWidth && gHeight) {
+ if (gWidth > 0 && gHeight > 0) {
gx = x + pci->metrics.leftSideBearing;
gy = y - pci->metrics.ascent;
if (glyph && gWidth <= sizeof(FbStip) * 8 &&
diff --git a/glamor/glamor_glyphblt.c b/glamor/glamor_glyphblt.c
index cada7bae7..d9665f778 100644
--- a/glamor/glamor_glyphblt.c
+++ b/glamor/glamor_glyphblt.c
@@ -90,7 +90,7 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc,
int h = GLYPHHEIGHTPIXELS(charinfo);
uint8_t *glyphbits = FONTGLYPHBITS(NULL, charinfo);
- if (w && h) {
+ if (w > 0 && h > 0) {
int glyph_x = x + charinfo->metrics.leftSideBearing;
int glyph_y = y - charinfo->metrics.ascent;
int glyph_stride = GLYPHWIDTHBYTESPADDED(charinfo);
diff --git a/mi/miglblt.c b/mi/miglblt.c
index 169d44ffc..8e33e90d8 100644
--- a/mi/miglblt.c
+++ b/mi/miglblt.c
@@ -143,7 +143,7 @@ miPolyGlyphBlt(DrawablePtr pDrawable, GC * pGC, int x, int y, unsigned int nglyp
pglyph = FONTGLYPHBITS(pglyphBase, pci);
gWidth = GLYPHWIDTHPIXELS(pci);
gHeight = GLYPHHEIGHTPIXELS(pci);
- if (gWidth && gHeight) {
+ if (gWidth > 0 && gHeight > 0) {
nbyGlyphWidth = GLYPHWIDTHBYTESPADDED(pci);
nbyPadGlyph = BitmapBytePad(gWidth);
--
2.54.0
From f3df3c9a52b4f480cbcff45cc6569c19de6bfede Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Sun, 31 May 2026 19:37:01 +1000
Subject: [PATCH xserver 2/2] glamor: reject fonts with per-glyph metrics
exceeding maxbounds
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
glamor_font_get() computes the atlas slot size from the font's declared
maxbounds, but copies each glyph's bitmap using the per-glyph metrics
(GLYPHHEIGHTPIXELS/GLYPHWIDTHBYTES macros). When a malicious PCF font
has per-glyph metrics exceeding maxbounds, the memcpy writes past the
heap-allocated atlas buffer. Negative per-glyph metrics are even worse:
the loop counter wraps to ~4 billion iterations (via unsigned cast) or
memcpy's size parameter wraps to SIZE_MAX.
The PCF parser in libXfont2 does not recompute maxbounds from per-glyph
data (only the BDF parser does), so the file's declared maxbounds values
are trusted as-is.
Reject fonts where any per-glyph metric is negative or exceeds the
atlas slot size, falling back to software rendering which uses per-glyph
metrics directly without an atlas.
This vulnerability was discovered by:
Anonymous working with Trend Micro Zero Day Initiative
CVE-2026-55999/ZDI-CAN-30498
Assisted-by: Claude:claude-opus-4-6
(cherry picked from commit fbf7bac22e2c6bd627fb042742a23318263edae1)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2252>
---
glamor/glamor_font.c | 30 +++++++++++++++++++++++++++---
1 file changed, 27 insertions(+), 3 deletions(-)
diff --git a/glamor/glamor_font.c b/glamor/glamor_font.c
index c689455c9..9c4941b05 100644
--- a/glamor/glamor_font.c
+++ b/glamor/glamor_font.c
@@ -71,6 +71,9 @@ glamor_font_get(ScreenPtr screen, FontPtr font)
glyph_width_pixels = font->info.maxbounds.rightSideBearing - font->info.minbounds.leftSideBearing;
glyph_height = font->info.maxbounds.ascent + font->info.maxbounds.descent;
+ if (glyph_width_pixels <= 0 || glyph_height <= 0)
+ return NULL;
+
glyph_width_bytes = (glyph_width_pixels + 7) >> 3;
glamor_font->glyph_width_pixels = glyph_width_pixels;
@@ -130,7 +133,28 @@ glamor_font_get(ScreenPtr screen, FontPtr font)
if (count) {
char *dst;
char *src = glyph->bits;
- unsigned y;
+ int gw = GLYPHWIDTHBYTES(glyph);
+ int gh = GLYPHHEIGHTPIXELS(glyph);
+
+ /* Reject fonts where any per-glyph metric is negative
+ * or exceeds the atlas slot size derived from maxbounds.
+ * The PCF parser in libXfont2 does not recompute
+ * maxbounds from per-glyph data, so a crafted PCF file
+ * can violate the maxbounds invariant.
+ *
+ * gw is passed as size_t to memcpy and a negative value
+ * would thus result in OOB access.
+ *
+ * Returning NULL makes glamor fall back to software
+ * rendering.
+ */
+ if (gw < 0 || gh < 0 ||
+ gw > glyph_width_bytes || gh > glyph_height) {
+ glDeleteTextures(1, &glamor_font->texture_id);
+ glamor_font->texture_id = 0;
+ free(bits);
+ return NULL;
+ }
dst = bits;
/* get offset of start of first row */
@@ -139,8 +163,8 @@ glamor_font_get(ScreenPtr screen, FontPtr font)
dst += (row & 1) ? glamor_font->row_width : 0;
dst += col * glyph_width_bytes;
- for (y = 0; y < GLYPHHEIGHTPIXELS(glyph); y++) {
- memcpy(dst, src, GLYPHWIDTHBYTES(glyph));
+ for (int y = 0; y < gh; y++) {
+ memcpy(dst, src, gw);
dst += overall_width;
src += GLYPHWIDTHBYTESPADDED(glyph);
}
--
2.54.0

View File

@ -46,7 +46,7 @@
Summary: X.Org X11 X server
Name: xorg-x11-server
Version: 1.20.11
Release: 28%{?gitdate:.%{gitdate}}%{?dist}.2
Release: 28%{?gitdate:.%{gitdate}}%{?dist}.3
URL: http://www.x.org
License: MIT
Group: User Interface/X
@ -295,6 +295,8 @@ Patch10127: 0051-glx-reject-negative-size-in-FeedbackBuffer-and-Selec.patch
Patch10128: 0001-dix-Silence-a-compiler-warning-in-doListFontsAndAlia.patch
# https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1257
Patch10129: 0001-xkb-fix-int-size-mismatch.patch
# CVE-2026-55999: glamor Font Atlas Heap Buffer Overflow
Patch10130: CVE-2026-55999.patch
BuildRequires: make
@ -724,6 +726,10 @@ find %{inst_srcdir}/hw/xfree86 -name \*.c -delete
%changelog
* Thu Jul 09 2026 Michel Dänzer <mdaenzer@redhat.com> - 1.20.11-28.3
- CVE fix for CVE-2026-55999
Resolves: https://redhat.atlassian.net/browse/RHEL-191504
* Fri Jun 12 2026 Olivier Fourdan <ofourdan@redhat.com> - 1.20.11-28.2
- Other security related fixes
Resolves: https://redhat.atlassian.net/browse/RHEL-184289