Version in base suite: 21.1.16-1.3+deb13u3 Base version: xorg-server_21.1.16-1.3+deb13u3 Target version: xorg-server_21.1.16-1.3+deb13u4 Base file: /srv/ftp-master.debian.org/ftp/pool/main/x/xorg-server/xorg-server_21.1.16-1.3+deb13u3.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/x/xorg-server/xorg-server_21.1.16-1.3+deb13u4.dsc debian/patches/GLX-Free-the-tag-of-the-old-context-later.patch | 62 ++++++ debian/patches/fb-mi-glamor-reject-glyphs-with-negative-dimensions.patch | 79 ++++++++ debian/patches/glamor-reject-fonts-with-per-glyph-metrics-exceeding.patch | 94 ++++++++++ debian/patches/glx-free-old-context-tag-before-allocating-new-one-i.patch | 60 ++++++ xorg-server-21.1.16/debian/changelog | 12 + xorg-server-21.1.16/debian/patches/series | 4 6 files changed, 311 insertions(+) diff -u xorg-server-21.1.16/debian/changelog xorg-server-21.1.16/debian/changelog --- xorg-server-21.1.16/debian/changelog +++ xorg-server-21.1.16/debian/changelog @@ -1,3 +1,15 @@ +xorg-server (2:21.1.16-1.3+deb13u4) trixie-security; urgency=high + + * Non-maintainer upload by the Security Team. + * GLX: Free the tag of the old context later + * glx: free old context tag before allocating new one in CommonMakeCurrent + (CVE-2026-56000) (Closes: #1141703) + * fb/mi/glamor: reject glyphs with negative dimensions + * glamor: reject fonts with per-glyph metrics exceeding maxbounds + (CVE-2026-55999) (Closes: #1141703) + + -- Salvatore Bonaccorso Sat, 05 Sep 2026 07:52:43 +0200 + xorg-server (2:21.1.16-1.3+deb13u3) trixie-security; urgency=high * Non-maintainer upload by the Security Team. diff -u xorg-server-21.1.16/debian/patches/series xorg-server-21.1.16/debian/patches/series --- xorg-server-21.1.16/debian/patches/series +++ xorg-server-21.1.16/debian/patches/series @@ -31,3 +31,7 @@ dix-increase-XLFDMAXFONTNAMELEN-to-match-libXfont2-s.patch dri2-Use-booleans-for-fake-front-buffer-tracking-in-.patch dri2-Deduplicate-attachments-in-do_get_buffer.patch +GLX-Free-the-tag-of-the-old-context-later.patch +glx-free-old-context-tag-before-allocating-new-one-i.patch +fb-mi-glamor-reject-glyphs-with-negative-dimensions.patch +glamor-reject-fonts-with-per-glyph-metrics-exceeding.patch only in patch2: unchanged: --- xorg-server-21.1.16.orig/debian/patches/GLX-Free-the-tag-of-the-old-context-later.patch +++ xorg-server-21.1.16/debian/patches/GLX-Free-the-tag-of-the-old-context-later.patch @@ -0,0 +1,62 @@ +From: =?UTF-8?q?Do=C4=9Fukan=20Korkmazt=C3=BCrk?= +Date: Tue, 22 Nov 2022 13:43:16 -0500 +Subject: GLX: Free the tag of the old context later +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Origin: https://gitlab.freedesktop.org/xorg/xserver/-/commit/d6fff22bc8b464dbadf3bc1fb858bd5a91c86849 + +In CommonMakeCurrent() function, the tag of the old context is freed +before the new context is made current. This is problematic because if +the CommonMakeNewCurrent() function fails, the tag of the old context +ends up being removed, even though it is still active. This causes +subsequent glXMakeCurrent() or glXMakeContextCurrent() requests to +generate a GLXBadContextTag error. + +This change moves the function call that frees the old tag to a location +where the result of CommonMakeNewCurrent() call is known and it is safe +to free it. + +Signed-off-by: Doğukan Korkmaztürk +(cherry picked from commit 4781f2a5a8c2c2b000374e2d87982a6701d5a6b3) + +Part-of: +--- + glx/vndcmds.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/glx/vndcmds.c b/glx/vndcmds.c +index d6d8719e124a..d1e088973680 100644 +--- a/glx/vndcmds.c ++++ b/glx/vndcmds.c +@@ -165,9 +165,6 @@ static int CommonLoseCurrent(ClientPtr client, GlxContextTagInfo *tagInfo) + tagInfo->tag, // No old context tag, + None, None, None, 0); + +- if (ret == Success) { +- GlxFreeContextTag(tagInfo); +- } + return ret; + } + +@@ -259,7 +256,6 @@ static int CommonMakeCurrent(ClientPtr client, + if (ret != Success) { + return ret; + } +- oldTag = NULL; + } + + if (newVendor != NULL) { +@@ -270,6 +266,9 @@ static int CommonMakeCurrent(ClientPtr client, + } else { + reply.contextTag = 0; + } ++ ++ GlxFreeContextTag(oldTag); ++ oldTag = NULL; + } + + reply.contextTag = GlxCheckSwap(client, reply.contextTag); +-- +2.55.0 + only in patch2: unchanged: --- xorg-server-21.1.16.orig/debian/patches/fb-mi-glamor-reject-glyphs-with-negative-dimensions.patch +++ xorg-server-21.1.16/debian/patches/fb-mi-glamor-reject-glyphs-with-negative-dimensions.patch @@ -0,0 +1,79 @@ +From: Peter Hutterer +Date: Mon, 1 Jun 2026 20:44:34 +1000 +Subject: fb/mi/glamor: reject glyphs with negative dimensions +Origin: https://gitlab.freedesktop.org/xorg/xserver/-/commit/0f1f4bcbfb1f23b800dfe386782d3a0f05b6756f + +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 1bdc2d4fd1b5..5c9318f5e436 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 cada7bae72b9..d9665f778648 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 169d44ffcdad..8e33e90d88fe 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.55.0 + only in patch2: unchanged: --- xorg-server-21.1.16.orig/debian/patches/glamor-reject-fonts-with-per-glyph-metrics-exceeding.patch +++ xorg-server-21.1.16/debian/patches/glamor-reject-fonts-with-per-glyph-metrics-exceeding.patch @@ -0,0 +1,94 @@ +From: Peter Hutterer +Date: Sun, 31 May 2026 19:37:01 +1000 +Subject: glamor: reject fonts with per-glyph metrics exceeding maxbounds +Origin: https://gitlab.freedesktop.org/xorg/xserver/-/commit/f3df3c9a52b4f480cbcff45cc6569c19de6bfede +Bug-Debian: https://bugs.debian.org/1141703 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-55999 + +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 c689455c9953..9c4941b058cf 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.55.0 + only in patch2: unchanged: --- xorg-server-21.1.16.orig/debian/patches/glx-free-old-context-tag-before-allocating-new-one-i.patch +++ xorg-server-21.1.16/debian/patches/glx-free-old-context-tag-before-allocating-new-one-i.patch @@ -0,0 +1,60 @@ +From: Peter Hutterer +Date: Sun, 31 May 2026 19:37:02 +1000 +Subject: glx: free old context tag before allocating new one in + CommonMakeCurrent +Origin: https://gitlab.freedesktop.org/xorg/xserver/-/commit/d6d96084f305a142eb3db7f720d7edd21e4c98b4 +Bug-Debian: https://bugs.debian.org/1141703 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-56000 + +oldTag in CommonMakeCurrent() is a pointer to cl->contextTags[...]. +CommonMakeCurrent() may realloc(cl->contextTags) and thus move the +memory, leaving oldTag as dangling pointer. + +If we then GlxFreeContextTag(oldTag) we end up writing into freed +memory. + +Fix this by freeing oldTag before CommonMakeNewCurrent(). + +This vulnerability was discovered by: +Anonymous working with Trend Micro Zero Day Initiative + +CVE-2026-56000/ZDI-CAN-30561 + +Fixes: 4781f2a5a8c2 ("GLX: Free the tag of the old context later") +Assisted-by: Claude:claude-opus-4-6 +(cherry picked from commit 2779affbdb4354e894f490e56f962527d6125043) + +Part-of: +--- + glx/vndcmds.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/glx/vndcmds.c b/glx/vndcmds.c +index d1e088973680..442c8e280910 100644 +--- a/glx/vndcmds.c ++++ b/glx/vndcmds.c +@@ -256,6 +256,11 @@ static int CommonMakeCurrent(ClientPtr client, + if (ret != Success) { + return ret; + } ++ // Free the old tag before calling CommonMakeNewCurrent(), ++ // which may call GlxAllocContextTag() and realloc the ++ // contextTags array, invalidating the oldTag pointer. ++ GlxFreeContextTag(oldTag); ++ oldTag = NULL; + } + + if (newVendor != NULL) { +@@ -266,9 +271,6 @@ static int CommonMakeCurrent(ClientPtr client, + } else { + reply.contextTag = 0; + } +- +- GlxFreeContextTag(oldTag); +- oldTag = NULL; + } + + reply.contextTag = GlxCheckSwap(client, reply.contextTag); +-- +2.55.0 +