diff --git a/CVE-2026-55999.patch b/CVE-2026-55999.patch new file mode 100644 index 0000000..e00f07e --- /dev/null +++ b/CVE-2026-55999.patch @@ -0,0 +1,179 @@ +From 0f1f4bcbfb1f23b800dfe386782d3a0f05b6756f Mon Sep 17 00:00:00 2001 +From: Peter Hutterer +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: +--- + 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 +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: +--- + 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 + diff --git a/xorg-x11-server.spec b/xorg-x11-server.spec index 007a6f1..ffbfbfc 100644 --- a/xorg-x11-server.spec +++ b/xorg-x11-server.spec @@ -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 - 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 - 1.20.11-28.2 - Other security related fixes Resolves: https://redhat.atlassian.net/browse/RHEL-184289