Fix CVE-2026-44950: heap buffer overflow in fs_read_glyphs()
Backport upstream fix for CVE-2026-44950 to libXfont2 2.0.3.
The fix adds a bounds-check for cumulative glyph data writes
in fs_read_glyphs() to prevent heap overflow from overlapping
source offsets sent by a malicious font server. A new regression
test (test-fserve-read-glyphs.c) is included to verify the fix.
CVE: CVE-2026-44950
Upstream patches:
- c2d222bb22.patch
Resolves: RHEL-222015
This commit was backported by Ymir, a Red Hat Enterprise Linux software maintenance AI agent.
Assisted-by: Ymir
This commit is contained in:
parent
5e3b29e401
commit
7505ca59ac
511
libXfont2-2.0.3-CVE-2026-44950.patch
Normal file
511
libXfont2-2.0.3-CVE-2026-44950.patch
Normal file
@ -0,0 +1,511 @@
|
||||
From fa38750d94ec161fc57d3f53d44a00bb1dfc3d89 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Mon, 13 Jul 2026 15:50:09 +1000
|
||||
Subject: [PATCH] fserve: bounds-check cumulative glyph data writes in
|
||||
fs_read_glyphs
|
||||
|
||||
fs_read_glyphs() copies each glyph's bitmap into a single allbits
|
||||
buffer allocated to rep->nbytes bytes. The per-glyph guard validates
|
||||
only that the source slice (position, length) lies within the pbitmaps
|
||||
source buffer. It does not check whether the running destination cursor
|
||||
has exceeded the allocation.
|
||||
|
||||
A malicious font server can send overlapping source offsets (e.g. 1000
|
||||
glyphs each referencing {position:0, length:64} with nbytes=64). Each
|
||||
individual source range passes validation, but the cumulative writes
|
||||
total 64000 bytes into a 64-byte destination buffer.
|
||||
|
||||
Interestingly there was an unconditional debug printf in place that
|
||||
sort-of warned about this but didn't prevent this. Let's remove that and
|
||||
instead use the actual check to bail out before we run OOB.
|
||||
|
||||
A regression test is included that sends 100 glyphs each referencing
|
||||
the same 64-byte source slice into a 64-byte destination buffer, and
|
||||
verifies the library rejects the overflow.
|
||||
|
||||
CVE-2026-44950
|
||||
|
||||
Found-by: Zhixi "Jace" Sun, independent security researcher
|
||||
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/36>
|
||||
---
|
||||
src/fc/fserve.c | 23 +-
|
||||
test/test-fserve-read-glyphs.c | 412 +++++++++++++++++++++++++++++++++
|
||||
2 files changed, 426 insertions(+), 9 deletions(-)
|
||||
create mode 100644 test/test-fserve-read-glyphs.c
|
||||
|
||||
diff --git a/src/fc/fserve.c b/src/fc/fserve.c
|
||||
index 708fc35..f17cffa 100644
|
||||
--- a/src/fc/fserve.c
|
||||
+++ b/src/fc/fserve.c
|
||||
@@ -1923,10 +1923,7 @@ fs_read_glyphs(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
|
||||
fsOffset32 local_off;
|
||||
char *off_adr;
|
||||
pointer pbitmaps;
|
||||
- char *bits, *allbits;
|
||||
-#ifdef DEBUG
|
||||
- char *origallbits;
|
||||
-#endif
|
||||
+ char *bits, *allbits, *origallbits;
|
||||
int i,
|
||||
err;
|
||||
int nranges = 0;
|
||||
@@ -2016,8 +2013,8 @@ fs_read_glyphs(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
|
||||
goto bail;
|
||||
}
|
||||
|
||||
-#ifdef DEBUG
|
||||
origallbits = allbits;
|
||||
+#ifdef DEBUG
|
||||
fprintf (stderr, "Reading %d glyphs in %d bytes for %s\n",
|
||||
(int) rep->num_chars, (int) rep->nbytes, fsd->name);
|
||||
#endif
|
||||
@@ -2038,6 +2035,18 @@ fs_read_glyphs(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
|
||||
(local_off.position < rep->nbytes) &&
|
||||
(local_off.length <= (rep->nbytes - local_off.position)))
|
||||
{
|
||||
+ /* Check that the destination buffer has enough room
|
||||
+ for this glyph to prevent a heap overflow from
|
||||
+ overlapping source offsets. */
|
||||
+ if (local_off.length >
|
||||
+ rep->nbytes - (allbits - origallbits))
|
||||
+ {
|
||||
+ ErrorF("fserve: glyph data overflow: "
|
||||
+ "cumulative write exceeds nbytes (%u)\n",
|
||||
+ (unsigned) rep->nbytes);
|
||||
+ err = AllocError;
|
||||
+ goto bail;
|
||||
+ }
|
||||
bits = allbits;
|
||||
allbits += local_off.length;
|
||||
memcpy(bits, (char *)pbitmaps + local_off.position,
|
||||
@@ -2065,10 +2074,6 @@ fs_read_glyphs(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
|
||||
}
|
||||
off_adr += SIZEOF(fsOffset32);
|
||||
}
|
||||
-#ifdef DEBUG
|
||||
- fprintf (stderr, "Used %d bytes instead of %d\n",
|
||||
- (int) (allbits - origallbits), (int) rep->nbytes);
|
||||
-#endif
|
||||
|
||||
if (blockrec->type == FS_OPEN_FONT)
|
||||
{
|
||||
diff --git a/test/test-fserve-read-glyphs.c b/test/test-fserve-read-glyphs.c
|
||||
new file mode 100644
|
||||
index 0000000..21c3410
|
||||
--- /dev/null
|
||||
+++ b/test/test-fserve-read-glyphs.c
|
||||
@@ -0,0 +1,412 @@
|
||||
+/*
|
||||
+ * Security regression tests for fs_read_glyphs() in src/fc/fserve.c.
|
||||
+ *
|
||||
+ * Approach: include fserve.c directly to access the static fs_read_glyphs()
|
||||
+ * function. Pre-fill the FSFpeRec.inBuf with a crafted protocol reply so
|
||||
+ * fs_get_reply() returns it without any network I/O.
|
||||
+ *
|
||||
+ * Copyright (c) 2026, Red Hat, Inc.
|
||||
+ *
|
||||
+ * Permission is hereby granted, free of charge, to any person obtaining a
|
||||
+ * copy of this software and associated documentation files (the "Software"),
|
||||
+ * to deal in the Software without restriction, including without limitation
|
||||
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
+ * and/or sell copies of the Software, and to permit persons to whom the
|
||||
+ * Software is furnished to do so, subject to the following conditions:
|
||||
+ *
|
||||
+ * The above copyright notice and this permission notice (including the next
|
||||
+ * paragraph) shall be included in all copies or substantial portions of the
|
||||
+ * Software.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
+ * DEALINGS IN THE SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * Include fserve.c directly to access the static fs_read_glyphs().
|
||||
+ * All non-static symbols from fserve.c are hidden in libXfont2.so
|
||||
+ * (via the linker version script), so there are no duplicate symbol
|
||||
+ * conflicts when linking against the library.
|
||||
+ */
|
||||
+#include "src/fc/fserve.c"
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+/*
|
||||
+ * Set up an FSFpeRec with its inBuf pre-filled with the given data.
|
||||
+ * fs_get_reply() will return this data without attempting any network I/O
|
||||
+ * because fs_inqueued(conn) >= size.
|
||||
+ */
|
||||
+static void
|
||||
+setup_conn(FSFpeRec *conn, const void *reply_data, long reply_size)
|
||||
+{
|
||||
+ memset(conn, 0, sizeof(*conn));
|
||||
+
|
||||
+ /*
|
||||
+ * fs_get_reply() checks: conn->fs_fd != -1 && conn->fs_listening
|
||||
+ * Use a dup'd fd so it's valid but harmless.
|
||||
+ */
|
||||
+ conn->fs_fd = dup(STDERR_FILENO);
|
||||
+ conn->fs_listening = TRUE;
|
||||
+
|
||||
+ /* Pre-fill the input buffer with our crafted reply */
|
||||
+ conn->inBuf.buf = malloc(reply_size);
|
||||
+ if (!conn->inBuf.buf) {
|
||||
+ fprintf(stderr, "FAIL: malloc for inBuf\n");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ memcpy(conn->inBuf.buf, reply_data, reply_size);
|
||||
+ conn->inBuf.size = reply_size;
|
||||
+ conn->inBuf.insert = reply_size;
|
||||
+ conn->inBuf.remove = 0;
|
||||
+ conn->inNeed = 0;
|
||||
+
|
||||
+ /* Allocate a minimal output buffer to keep _fs_flush happy */
|
||||
+ conn->outBuf.buf = calloc(1, FS_BUF_INC);
|
||||
+ conn->outBuf.size = FS_BUF_INC;
|
||||
+ conn->outBuf.insert = 0;
|
||||
+ conn->outBuf.remove = 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+cleanup_conn(FSFpeRec *conn)
|
||||
+{
|
||||
+ if (conn->fs_fd >= 0)
|
||||
+ close(conn->fs_fd);
|
||||
+ free(conn->inBuf.buf);
|
||||
+ free(conn->outBuf.buf);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Set up the minimum font state needed by fs_read_glyphs():
|
||||
+ * - FontPathElementRec (fpe) with fpe->private = conn
|
||||
+ * - FontRec (pfont) with info, fontPrivate, fpePrivate
|
||||
+ * - FSFontRec (fsfont) with encoding[] array
|
||||
+ * - FSFontDataRec (fsd)
|
||||
+ * - FSBlockDataRec (blockrec) of type FS_OPEN_FONT
|
||||
+ * - FSBlockedFontRec (bfont) embedded in blockrec->data
|
||||
+ */
|
||||
+struct test_font_state {
|
||||
+ FontPathElementRec fpe;
|
||||
+ FontRec pfont;
|
||||
+ FSFontRec fsfont;
|
||||
+ FSFontDataRec fsd;
|
||||
+ FSBlockDataRec blockrec;
|
||||
+ FSBlockedFontRec bfont;
|
||||
+ CharInfoPtr encoding;
|
||||
+};
|
||||
+
|
||||
+static void
|
||||
+setup_font_state(struct test_font_state *s, FSFpeRec *conn,
|
||||
+ int num_encoding)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ memset(s, 0, sizeof(*s));
|
||||
+
|
||||
+ /* Font path element */
|
||||
+ s->fpe.name = (char *)"test-fserve";
|
||||
+ s->fpe.name_length = strlen(s->fpe.name);
|
||||
+ s->fpe.private = conn;
|
||||
+
|
||||
+ /* Font data (fpePrivate) */
|
||||
+ s->fsd.name = (char *)"test-font";
|
||||
+ s->fsd.namelen = strlen(s->fsd.name);
|
||||
+ s->fsd.glyphs_to_get = 0;
|
||||
+
|
||||
+ /* Encoding array -- this is what num_extents sized */
|
||||
+ s->encoding = calloc(num_encoding, sizeof(CharInfoRec));
|
||||
+ if (!s->encoding) {
|
||||
+ fprintf(stderr, "FAIL: calloc encoding\n");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ /* Mark all glyphs as having nonzero metrics and undefined bits
|
||||
+ * so fs_read_glyphs will try to process them */
|
||||
+ for (i = 0; i < num_encoding; i++) {
|
||||
+ s->encoding[i].metrics.ascent = 10;
|
||||
+ s->encoding[i].metrics.descent = 2;
|
||||
+ s->encoding[i].metrics.characterWidth = 8;
|
||||
+ s->encoding[i].metrics.leftSideBearing = 0;
|
||||
+ s->encoding[i].metrics.rightSideBearing = 8;
|
||||
+ s->encoding[i].bits = &_fs_glyph_undefined;
|
||||
+ }
|
||||
+
|
||||
+ /* FSFontRec */
|
||||
+ s->fsfont.encoding = s->encoding;
|
||||
+ s->fsfont.num_encoding = num_encoding;
|
||||
+ s->fsfont.pDefault = NULL;
|
||||
+ s->fsfont.inkMetrics = s->encoding;
|
||||
+ s->fsfont.glyphs = NULL;
|
||||
+
|
||||
+ /* FontRec */
|
||||
+ s->pfont.fontPrivate = &s->fsfont;
|
||||
+ s->pfont.fpePrivate = &s->fsd;
|
||||
+ s->pfont.fpe = &s->fpe;
|
||||
+ s->pfont.info.firstRow = 0;
|
||||
+ s->pfont.info.lastRow = 0;
|
||||
+ s->pfont.info.firstCol = 0;
|
||||
+ s->pfont.info.lastCol = num_encoding > 0 ? num_encoding - 1 : 0;
|
||||
+ s->pfont.info.maxbounds.ascent = 20;
|
||||
+ s->pfont.info.maxbounds.descent = 10;
|
||||
+ s->pfont.info.maxbounds.characterWidth = 20;
|
||||
+
|
||||
+ /* Block record -- simulating FS_OPEN_FONT path */
|
||||
+ s->bfont.pfont = &s->pfont;
|
||||
+ s->bfont.flags = FontLoadBitmaps;
|
||||
+ s->bfont.state = FS_GLYPHS_REPLY;
|
||||
+ s->bfont.freeFont = FALSE;
|
||||
+
|
||||
+ s->blockrec.type = FS_OPEN_FONT;
|
||||
+ s->blockrec.data = (pointer)&s->bfont;
|
||||
+ s->blockrec.client = NULL;
|
||||
+ s->blockrec.sequenceNumber = 0;
|
||||
+ s->blockrec.errcode = 0;
|
||||
+ s->blockrec.depending = NULL;
|
||||
+ s->blockrec.next = NULL;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+cleanup_font_state(struct test_font_state *s)
|
||||
+{
|
||||
+ FSGlyphPtr g, next;
|
||||
+
|
||||
+ /* Free any glyph allocations made by fs_alloc_glyphs */
|
||||
+ for (g = s->fsfont.glyphs; g; g = next) {
|
||||
+ next = g->next;
|
||||
+ free(g);
|
||||
+ }
|
||||
+ free(s->encoding);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Build a crafted fsQueryXBitmaps16Reply in a buffer.
|
||||
+ * Returns the total buffer size. Caller must free *out_buf.
|
||||
+ *
|
||||
+ * The reply contains:
|
||||
+ * - fsQueryXBitmaps16Reply header
|
||||
+ * - num_chars fsOffset32 entries
|
||||
+ * - nbytes of bitmap data
|
||||
+ */
|
||||
+static long
|
||||
+build_reply(char **out_buf,
|
||||
+ CARD32 num_chars, CARD32 nbytes,
|
||||
+ CARD32 off_position, CARD32 off_length)
|
||||
+{
|
||||
+ long hdr_size = SIZEOF(fsQueryXBitmaps16Reply);
|
||||
+ long offsets_size = SIZEOF(fsOffset32) * num_chars;
|
||||
+ /* Bitmap data area: at least nbytes, but we need off_position + off_length
|
||||
+ * to be valid source, so ensure bitmap area is large enough */
|
||||
+ long bitmap_size = nbytes;
|
||||
+ long total = hdr_size + offsets_size + bitmap_size;
|
||||
+ long total_padded = (total + 3) & ~3; /* pad to 4 bytes */
|
||||
+ char *buf;
|
||||
+ fsQueryXBitmaps16Reply *rep;
|
||||
+ fsOffset32 off;
|
||||
+ long i;
|
||||
+
|
||||
+ buf = calloc(1, total_padded);
|
||||
+ if (!buf) {
|
||||
+ fprintf(stderr, "FAIL: calloc reply buffer\n");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ /* Fill header */
|
||||
+ rep = (fsQueryXBitmaps16Reply *)buf;
|
||||
+ rep->type = FS_Reply; /* normal reply (0), not FS_Error (1) */
|
||||
+ rep->sequenceNumber = 0;
|
||||
+ rep->length = total_padded >> 2; /* length in 32-bit words */
|
||||
+ rep->replies_hint = 0;
|
||||
+ rep->num_chars = num_chars;
|
||||
+ rep->nbytes = nbytes;
|
||||
+
|
||||
+ /* Fill offset entries -- all pointing to the same source range */
|
||||
+ off.position = off_position;
|
||||
+ off.length = off_length;
|
||||
+ for (i = 0; i < (long)num_chars; i++) {
|
||||
+ memcpy(buf + hdr_size + i * SIZEOF(fsOffset32),
|
||||
+ &off, SIZEOF(fsOffset32));
|
||||
+ }
|
||||
+
|
||||
+ /* Fill bitmap data with recognizable pattern */
|
||||
+ memset(buf + hdr_size + offsets_size, 0xAA, bitmap_size);
|
||||
+
|
||||
+ *out_buf = buf;
|
||||
+ return total_padded;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Test 1: num_chars > num_encoding
|
||||
+ *
|
||||
+ * Allocate encoding[] with 2 entries, but send a reply with
|
||||
+ * num_chars = 100. Without the fix, this would read/write
|
||||
+ * encoding[2..99] out of bounds.
|
||||
+ */
|
||||
+static int
|
||||
+test_num_chars_exceeds_encoding(void)
|
||||
+{
|
||||
+ FSFpeRec conn;
|
||||
+ struct test_font_state state;
|
||||
+ char *reply_buf;
|
||||
+ long reply_size;
|
||||
+ int result;
|
||||
+ int num_encoding = 2;
|
||||
+ CARD32 num_chars = 100;
|
||||
+ CARD32 nbytes = num_chars * 16; /* enough bitmap data */
|
||||
+
|
||||
+ /* Build a reply with num_chars=100 but valid source data */
|
||||
+ reply_size = build_reply(&reply_buf, num_chars, nbytes, 0, 16);
|
||||
+ setup_conn(&conn, reply_buf, reply_size);
|
||||
+ setup_font_state(&state, &conn, num_encoding);
|
||||
+
|
||||
+ result = fs_read_glyphs(&state.fpe, &state.blockrec);
|
||||
+
|
||||
+ cleanup_font_state(&state);
|
||||
+ cleanup_conn(&conn);
|
||||
+ free(reply_buf);
|
||||
+
|
||||
+ if (result != Successful) {
|
||||
+ printf("ok 1 - num_chars (%u) > num_encoding (%d) rejected\n",
|
||||
+ (unsigned)num_chars, num_encoding);
|
||||
+ return 0;
|
||||
+ } else {
|
||||
+ printf("not ok 1 - num_chars (%u) > num_encoding (%d) "
|
||||
+ "should have been rejected\n",
|
||||
+ (unsigned)num_chars, num_encoding);
|
||||
+ return 1;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Test 2: cumulative glyph data overflow
|
||||
+ *
|
||||
+ * Allocate allbits with nbytes=64, but send 100 glyphs each
|
||||
+ * with offset {position:0, length:64}. Each individual source
|
||||
+ * range is valid, but the cumulative writes total 6400 bytes
|
||||
+ * into a 64-byte buffer.
|
||||
+ */
|
||||
+static int
|
||||
+test_cumulative_allbits_overflow(void)
|
||||
+{
|
||||
+ FSFpeRec conn;
|
||||
+ struct test_font_state state;
|
||||
+ char *reply_buf;
|
||||
+ long reply_size;
|
||||
+ int result;
|
||||
+ int num_encoding = 100; /* match num_chars so encoding[] is fine */
|
||||
+ CARD32 num_chars = 100;
|
||||
+ CARD32 nbytes = 64; /* tiny destination buffer */
|
||||
+
|
||||
+ /* All offsets point to {position:0, length:64} -- each source
|
||||
+ * range is valid but they overlap, causing 100*64=6400 bytes
|
||||
+ * to be written to a 64-byte buffer */
|
||||
+ reply_size = build_reply(&reply_buf, num_chars, nbytes, 0, 64);
|
||||
+ setup_conn(&conn, reply_buf, reply_size);
|
||||
+ setup_font_state(&state, &conn, num_encoding);
|
||||
+
|
||||
+ result = fs_read_glyphs(&state.fpe, &state.blockrec);
|
||||
+
|
||||
+ cleanup_font_state(&state);
|
||||
+ cleanup_conn(&conn);
|
||||
+ free(reply_buf);
|
||||
+
|
||||
+ if (result != Successful) {
|
||||
+ printf("ok 2 - cumulative allbits overflow (100 * 64 into 64) rejected\n");
|
||||
+ return 0;
|
||||
+ } else {
|
||||
+ printf("not ok 2 - cumulative allbits overflow (100 * 64 into 64) "
|
||||
+ "should have been rejected\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Test 3: legitimate reply should still be accepted
|
||||
+ *
|
||||
+ * num_chars == num_encoding, each glyph has unique non-overlapping
|
||||
+ * offsets, and total data fits in nbytes.
|
||||
+ */
|
||||
+static int
|
||||
+test_legitimate_reply(void)
|
||||
+{
|
||||
+ FSFpeRec conn;
|
||||
+ struct test_font_state state;
|
||||
+ char *reply_buf;
|
||||
+ long hdr_size = SIZEOF(fsQueryXBitmaps16Reply);
|
||||
+ long offsets_size;
|
||||
+ int result;
|
||||
+ int num_encoding = 4;
|
||||
+ CARD32 num_chars = 4;
|
||||
+ CARD32 glyph_size = 16;
|
||||
+ CARD32 nbytes = num_chars * glyph_size;
|
||||
+ long total, total_padded;
|
||||
+ fsQueryXBitmaps16Reply *rep;
|
||||
+ fsOffset32 off;
|
||||
+ int i;
|
||||
+
|
||||
+ offsets_size = SIZEOF(fsOffset32) * num_chars;
|
||||
+ total = hdr_size + offsets_size + nbytes;
|
||||
+ total_padded = (total + 3) & ~3;
|
||||
+
|
||||
+ reply_buf = calloc(1, total_padded);
|
||||
+ if (!reply_buf) {
|
||||
+ fprintf(stderr, "FAIL: calloc\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ rep = (fsQueryXBitmaps16Reply *)reply_buf;
|
||||
+ rep->type = FS_Reply;
|
||||
+ rep->sequenceNumber = 0;
|
||||
+ rep->length = total_padded >> 2;
|
||||
+ rep->replies_hint = 0;
|
||||
+ rep->num_chars = num_chars;
|
||||
+ rep->nbytes = nbytes;
|
||||
+
|
||||
+ /* Each glyph gets its own non-overlapping slice */
|
||||
+ for (i = 0; i < (int)num_chars; i++) {
|
||||
+ off.position = i * glyph_size;
|
||||
+ off.length = glyph_size;
|
||||
+ memcpy(reply_buf + hdr_size + i * SIZEOF(fsOffset32),
|
||||
+ &off, SIZEOF(fsOffset32));
|
||||
+ }
|
||||
+ memset(reply_buf + hdr_size + offsets_size, 0xBB, nbytes);
|
||||
+
|
||||
+ setup_conn(&conn, reply_buf, total_padded);
|
||||
+ setup_font_state(&state, &conn, num_encoding);
|
||||
+
|
||||
+ result = fs_read_glyphs(&state.fpe, &state.blockrec);
|
||||
+
|
||||
+ cleanup_font_state(&state);
|
||||
+ cleanup_conn(&conn);
|
||||
+ free(reply_buf);
|
||||
+
|
||||
+ if (result == Successful) {
|
||||
+ printf("ok 3 - legitimate reply (4 glyphs, non-overlapping) accepted\n");
|
||||
+ return 0;
|
||||
+ } else {
|
||||
+ printf("not ok 3 - legitimate reply (4 glyphs, non-overlapping) "
|
||||
+ "rejected with error %d\n", result);
|
||||
+ return 1;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+main(int argc, char **argv)
|
||||
+{
|
||||
+ int failures = 0;
|
||||
+
|
||||
+ printf("1..3\n");
|
||||
+
|
||||
+ failures += test_num_chars_exceeds_encoding();
|
||||
+ failures += test_cumulative_allbits_overflow();
|
||||
+ failures += test_legitimate_reply();
|
||||
+
|
||||
+ return failures ? 1 : 0;
|
||||
+}
|
||||
@ -1,7 +1,7 @@
|
||||
Summary: X.Org X11 libXfont2 runtime library
|
||||
Name: libXfont2
|
||||
Version: 2.0.3
|
||||
Release: 2%{?dist}.1
|
||||
Release: 2%{?dist}.2
|
||||
License: MIT
|
||||
Group: System Environment/Libraries
|
||||
URL: http://www.x.org
|
||||
@ -19,6 +19,9 @@ Patch1: 0001-bitscale-fix-integer-overflow-in-BitmapScaleBitmaps-.patch
|
||||
Patch2: 0002-pcfread-validate-bitmap-sizes-and-offsets-against-pe.patch
|
||||
Patch3: 0003-bitscale-add-bounds-check-to-computeProps-for-proper.patch
|
||||
|
||||
# https://gitlab.freedesktop.org/xorg/lib/libxfont/-/commit/c2d222bb22c623d8a40f3275077fc7e6617f2c8a
|
||||
Patch4: libXfont2-2.0.3-CVE-2026-44950.patch
|
||||
|
||||
%description
|
||||
X.Org X11 libXfont2 runtime library
|
||||
|
||||
@ -60,6 +63,10 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
|
||||
%{_libdir}/pkgconfig/xfont2.pc
|
||||
|
||||
%changelog
|
||||
* Thu Aug 06 2026 RHEL Packaging Agent <redhat-ymir-agent@redhat.com> - 2.0.3-2.2
|
||||
- CVE fix for: CVE-2026-44950
|
||||
Resolves: https://redhat.atlassian.net/browse/RHEL-222015
|
||||
|
||||
* Wed Jul 08 2026 Olivier Fourdan <ofourdan@redhat.com> - 2.0.3-2.1
|
||||
- CVE fix for: CVE-2026-56001, CVE-2026-56002, CVE-2026-56003
|
||||
Resolves: https://redhat.atlassian.net/browse/RHEL-191877
|
||||
|
||||
Loading…
Reference in New Issue
Block a user