libxfont2: Fix CVE-2026-56002

Pick patch according to [2]

[1] https://nvd.nist.gov/vuln/detail/CVE-2026-56002
[2] https://security-tracker.debian.org/tracker/CVE-2026-56002

(From OE-Core rev: 1b47a4e636bbda15b00379ac7a732ffade7a6274)

Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
Signed-off-by: Yoann Congal <yoann.congal@smile.fr>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Vijay Anusuri
2026-08-24 18:26:52 +05:30
committed by Richard Purdie
parent 28e31d5c6b
commit bd2ef0458c
2 changed files with 139 additions and 0 deletions

View File

@@ -0,0 +1,138 @@
From b4389e0b1d84a690b819bb27b1439968811a3674f Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Mon, 1 Jun 2026 16:48:40 +1000
Subject: [PATCH] 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 <peter.hutterer@who-t.net>
Part-of: <https://gitlab.freedesktop.org/xorg/lib/libxfont/-/merge_requests/34>
Upstream-Status: Backport [https://gitlab.freedesktop.org/xorg/lib/libxfont/-/commit/b4389e0b1d84a690b819bb27b1439968811a3674]
CVE: CVE-2026-56002
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
---
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)]=
--
2.43.0

View File

@@ -16,6 +16,7 @@ XORG_PN = "libXfont2"
BBCLASSEXTEND = "native"
SRC_URI += "file://CVE-2026-56001.patch \
file://CVE-2026-56002.patch \
"
SRC_URI[sha256sum] = "74ca20017eb0fb3f56d8d5e60685f560fc85e5ff3d84c61c4cb891e40c27aef4"