Bug#1141911: trixie-pu: package libxfont/2.0.6-2+deb13u1
Andrej Shadura <[email protected]>
| Newsgroups | gmane.linux.debian.devel.release |
|---|---|
| Organization | Debian |
| Message-ID | <e2fdf6a4-4be9-4c6f-beb8-ec0d727f6757__20739.3656413601$1783872812$gmane$org@debian.org> |
Hello, On Sun, 12 Jul 2026 17:30:32 +0200 Andrej Shadura <[email protected]> wrote: > Package: release.debian.org > Severity: normal > Tags: trixie > X-Debbugs-Cc: [email protected], Timo Aaltonen <[email protected]> > Control: affects -1 + src:libxfont > User: [email protected] > Usertags: pu > > [ Reason ] > This upload fixes three recent CVEs, see https://bugs.debian.org/1141702 > for more context. We’re fixing these in bookworm and bullseye as part of > the Debian LTS project. > > [ Impact ] > Users of trixie would be impacted by these security issues. Users > upgrading from LTS would find themselves facing them again. > > [ Tests ] > No automated tests. Only build testing was done. > (What automated or manual tests cover the affected code?) > > [ Risks ] > (Discussion of the risks involved. E.g. code is trivial or > complex, alternatives available.) > > [ Checklist ] > [x] *all* changes are documented in the d/changelog > [x] I reviewed all changes and I approve them > [x] attach debdiff against the package in (old)stable > [x] the issue is verified as fixed in unstable > > [ Changes ] > The changes are only clean cherry-picks of the upstream commits. As it happens, I didn’t attach the debdiff initially. -- Cheers, Andrej
libxfont_2.0.6-2+deb13u1.debdiff
(text/plain, 12.8 KB)
diff --git a/debian/changelog b/debian/changelog index 60002827f386..274f848559f5 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,12 @@ +libxfont (1:2.0.6-2+deb13u1) trixie; urgency=medium + + * Add upstream patches for security issues: + - CVE-2026-56001: integer overflow in BitmapScaleBitmaps bytestoalloc + - CVE-2026-56002: validate bitmap sizes and offsets in pcfread + - CVE-2026-56003: bounds check to computeProps for property buffer + + -- Andrej Shadura <[email protected]> Sun, 12 Jul 2026 16:45:15 +0200 + libxfont (1:2.0.6-2) unstable; urgency=medium * Team upload diff --git a/debian/patches/CVE-2026-56001.patch b/debian/patches/CVE-2026-56001.patch new file mode 100644 index 000000000000..6a2df72474de --- /dev/null +++ b/debian/patches/CVE-2026-56001.patch @@ -0,0 +1,68 @@ +From: Peter Hutterer <[email protected]> +Date: Mon, 1 Jun 2026 16:46:10 +1000 +Subject: 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 <[email protected]> +Part-of: <https://gitlab.freedesktop.org/xorg/lib/libxfont/-/merge_requests/34> + +Origin: upstream, https://gitlab.freedesktop.org/xorg/lib/libxfont/-/commit/be0b08e2d354138d3222b4490e2a77c6ee42f778 +--- + src/bitmap/bitscale.c | 23 ++++++++++++++++++++--- + 1 file changed, 20 insertions(+), 3 deletions(-) + +diff --git a/src/bitmap/bitscale.c b/src/bitmap/bitscale.c +index e29ba96..7100138 100644 +--- a/src/bitmap/bitscale.c ++++ b/src/bitmap/bitscale.c +@@ -1460,7 +1460,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]; +@@ -1487,8 +1487,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 ? */ diff --git a/debian/patches/CVE-2026-56002.patch b/debian/patches/CVE-2026-56002.patch new file mode 100644 index 000000000000..d3bd18042d25 --- /dev/null +++ b/debian/patches/CVE-2026-56002.patch @@ -0,0 +1,131 @@ +From: Peter Hutterer <[email protected]> +Date: Mon, 1 Jun 2026 16:48:40 +1000 +Subject: 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 <[email protected]> +Part-of: <https://gitlab.freedesktop.org/xorg/lib/libxfont/-/merge_requests/34> + +Origin: upstream, https://gitlab.freedesktop.org/xorg/lib/libxfont/-/commit/b4389e0b1d84a690b819bb27b1439968811a3674 +--- + 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 882318b..bcb82b8 100644 +--- a/src/bitmap/pcfread.c ++++ b/src/bitmap/pcfread.c +@@ -531,25 +531,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]; +@@ -624,6 +673,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)]= diff --git a/debian/patches/CVE-2026-56003.patch b/debian/patches/CVE-2026-56003.patch new file mode 100644 index 000000000000..6bd5f07b0848 --- /dev/null +++ b/debian/patches/CVE-2026-56003.patch @@ -0,0 +1,107 @@ +From: Peter Hutterer <[email protected]> +Date: Mon, 1 Jun 2026 16:49:55 +1000 +Subject: 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 <[email protected]> +Part-of: <https://gitlab.freedesktop.org/xorg/lib/libxfont/-/merge_requests/34> + +Origin: upstream, https://gitlab.freedesktop.org/xorg/lib/libxfont/-/commit/dff957a5158da038a282a59a31fe736702732939 +--- + src/bitmap/bitscale.c | 41 +++++++++++++++++++++-------------------- + 1 file changed, 21 insertions(+), 20 deletions(-) + +diff --git a/src/bitmap/bitscale.c b/src/bitmap/bitscale.c +index 7100138..1fd15be 100644 +--- a/src/bitmap/bitscale.c ++++ b/src/bitmap/bitscale.c +@@ -511,7 +511,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; +@@ -526,25 +527,13 @@ 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; +- break; +- case unscaled: +- npf->value = pf->value; +- npf->name = pf->name; +- npf++; +- count++; +- *isStringProp++ = *wasStringProp; +- break; +- default: +- break; +- } +- if (t->type != unscaled) +- { ++ 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++; +@@ -554,6 +543,18 @@ computeProps(FontPropPtr pf, char *wasStringProp, + count++; + *isStringProp++ = *wasStringProp; + *isStringProp++ = *wasStringProp; ++ break; ++ case unscaled: ++ if (count + 1 > maxprops) ++ continue; ++ npf->value = pf->value; ++ npf->name = pf->name; ++ npf++; ++ count++; ++ *isStringProp++ = *wasStringProp; ++ break; ++ default: ++ break; + } + } + return count; +@@ -671,7 +672,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; + } + diff --git a/debian/patches/series b/debian/patches/series index fdffa2a0fd7b..7d05b9a86497 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1 +1,3 @@ -# placeholder +CVE-2026-56001.patch +CVE-2026-56002.patch +CVE-2026-56003.patch