Backport the upstream fix fpr CVE-2026-4367, in which the `xpmNextWord()` function could attempt to read beyond the file's end due to improper validation of file boundaries.
Reference: https://nvd.nist.gov/vuln/detail/CVE-2026-4367 Signed-off-by: Enoch Ng <[email protected]> --- ...67-Out-of-bounds-read-in-xpmNextWord.patch | 139 ++++++++++++++++++ .../xorg-lib/libxpm_3.5.17.bb | 1 + 2 files changed, 140 insertions(+) create mode 100644 meta/recipes-graphics/xorg-lib/libxpm/0001-Fix-CVE-2026-4367-Out-of-bounds-read-in-xpmNextWord.patch diff --git a/meta/recipes-graphics/xorg-lib/libxpm/0001-Fix-CVE-2026-4367-Out-of-bounds-read-in-xpmNextWord.patch b/meta/recipes-graphics/xorg-lib/libxpm/0001-Fix-CVE-2026-4367-Out-of-bounds-read-in-xpmNextWord.patch new file mode 100644 index 0000000000..e1320b597d --- /dev/null +++ b/meta/recipes-graphics/xorg-lib/libxpm/0001-Fix-CVE-2026-4367-Out-of-bounds-read-in-xpmNextWord.patch @@ -0,0 +1,139 @@ +From 5448e1bd7252780b16db869c2253d24e0fe0ae18 Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan <[email protected]> +Date: Tue, 17 Feb 2026 11:59:56 +0100 +Subject: [PATCH libXpm] Fix CVE-2026-4367: Out-of-bounds read in xpmNextWord() + +xpmNextWord() checks for the terminator character to detect the end of +the file, but a very small malformed XPM file may cause the function to +read past the end of the buffer, causing out-of-bound reads: + + == Invalid read of size 1 + == at 0x48AD3A4: xpmParseColors (parse.c:239) + == by 0x48AF9D8: xpmParseData (parse.c:783) + == by 0x48B1C18: XpmCreateXpmImageFromBuffer (CrIFrBuf.c:101) + == by 0x4005A6: main () + == Address 0x4c413bf is 0 bytes after a block of size 15 alloc'd + == at 0x4841B26: malloc (vg_replace_malloc.c:447) + == by 0x48B2809: XpmReadFileToBuffer (RdFToBuf.c:96) + == by 0x400554: main () + == + == Invalid read of size 1 + == at 0x48AC8D5: xpmNextWord.constprop.0 (data.c:262) + == by 0x48AD492: xpmParseColors (parse.c:266) + == by 0x48AF9D8: xpmParseData (parse.c:783) + == by 0x48B1C18: XpmCreateXpmImageFromBuffer (CrIFrBuf.c:101) + == by 0x4005A6: main () + == Address 0x4c413c0 is 1 bytes after a block of size 15 alloc'd + == at 0x4841B26: malloc (vg_replace_malloc.c:447) + == by 0x48B2809: XpmReadFileToBuffer (RdFToBuf.c:96) + == by 0x400554: main () + == + == Invalid read of size 1 + == at 0x48AC965: xpmNextWord.constprop.0 (data.c:265) + == by 0x48AD492: xpmParseColors (parse.c:266) + == by 0x48AF9D8: xpmParseData (parse.c:783) + == by 0x48B1C18: XpmCreateXpmImageFromBuffer (CrIFrBuf.c:101) + == by 0x4005A6: main () + == Address 0x4c413c0 is 1 bytes after a block of size 15 alloc'd + == at 0x4841B26: malloc (vg_replace_malloc.c:447) + == by 0x48B2809: XpmReadFileToBuffer (RdFToBuf.c:96) + == by 0x400554: main () + +The problem actually comes from xpmNextString() and xpmParseColors(): + +1) xpmNextString() checks for the NULL terminator when looking for the + end of the string (Eos) but not when looking for the beginning of the + next string (Bos). + +2) xpmParseColors() does not check the return value from xpmNextString() + and continues even when xpmNextString() raised an invalid XPM file. + +To avoid the issue, fix xpmNextString() to check for the NULL string +terminator when looking for the beginning of the next string and fix +xpmParseColors() to stop when xpmNextString() reported an invalid XPM +error. + +CVE-2026-4367 + +This vulnerability was discovered by: +Naoki Wakamatsu + +v2: Fix the XPM 1 code path the same. + +Signed-off-by: Olivier Fourdan <[email protected]> +Part-of: <https://gitlab.freedesktop.org/xorg/lib/libxpm/-/merge_requests/31> + +Upstream-Status: Backport [https://gitlab.freedesktop.org/xorg/lib/libxpm/-/commit/5448e1bd7252780b16db869c2253d24e0fe0ae18] +Signed-off-by: Enoch Ng <[email protected]> + +--- + + src/data.c | 3 +++ + src/parse.c | 19 ++++++++++++++----- + 2 files changed, 17 insertions(+), 5 deletions(-) + +diff --git a/src/data.c b/src/data.c +index 6e87455..a2b4acc 100644 +--- a/src/data.c ++++ b/src/data.c +@@ -210,6 +210,9 @@ xpmNextString(xpmData *data) + while ((c = *data->cptr++) && c != data->Bos && c != '\0') + if (data->Bcmt && c == data->Bcmt[0]) + ParseComment(data); ++ ++ if (c == '\0') ++ return XpmFileInvalid; + } else if (data->Bcmt) { /* XPM2 natural */ + while (((c = *data->cptr++) == data->Bcmt[0]) && c != '\0') + ParseComment(data); +diff --git a/src/parse.c b/src/parse.c +index cd923f9..268954d 100644 +--- a/src/parse.c ++++ b/src/parse.c +@@ -216,7 +216,9 @@ xpmParseColors( + + if (!data->format) { /* XPM 2 or 3 */ + for (a = 0, color = colorTable; a < ncolors; a++, color++) { +- xpmNextString(data); /* skip the line */ ++ ErrorStatus = xpmNextString(data); /* skip the line */ ++ if (ErrorStatus != XpmSuccess) ++ goto error; + + /* + * read pixel value +@@ -314,7 +316,9 @@ xpmParseColors( + /* get to the beginning of the first string */ + data->Bos = '"'; + data->Eos = '\0'; +- xpmNextString(data); ++ ErrorStatus = xpmNextString(data); ++ if (ErrorStatus != XpmSuccess) ++ goto error; + data->Eos = '"'; + for (a = 0, color = colorTable; a < ncolors; a++, color++) { + +@@ -354,7 +358,9 @@ xpmParseColors( + /* + * read color values + */ +- xpmNextString(data); /* get to the next string */ ++ ErrorStatus = xpmNextString(data); /* get to the next string */ ++ if (ErrorStatus != XpmSuccess) ++ goto error; + *curbuf = '\0'; /* init curbuf */ + while ((l = xpmNextWord(data, buf, BUFSIZ))) { + if (*curbuf != '\0') { +@@ -378,8 +384,11 @@ xpmParseColors( + memcpy(s, curbuf, len); + color->c_color = s; + *curbuf = '\0'; /* reset curbuf */ +- if (a < ncolors - 1) /* can we trust ncolors -> leave data's bounds */ +- xpmNextString(data); /* get to the next string */ ++ if (a < ncolors - 1) { /* can we trust ncolors -> leave data's bounds */ ++ ErrorStatus = xpmNextString(data); /* get to the next string */ ++ if (ErrorStatus != XpmSuccess) ++ goto error; ++ } + } + } + *colorTablePtr = colorTable; diff --git a/meta/recipes-graphics/xorg-lib/libxpm_3.5.17.bb b/meta/recipes-graphics/xorg-lib/libxpm_3.5.17.bb index 8e15ecc0d4..9d1dd47742 100644 --- a/meta/recipes-graphics/xorg-lib/libxpm_3.5.17.bb +++ b/meta/recipes-graphics/xorg-lib/libxpm_3.5.17.bb @@ -22,6 +22,7 @@ PACKAGES =+ "sxpm cxpm" FILES:cxpm = "${bindir}/cxpm" FILES:sxpm = "${bindir}/sxpm" +SRC_URI += " file://0001-Fix-CVE-2026-4367-Out-of-bounds-read-in-xpmNextWord.patch" SRC_URI[sha256sum] = "64b31f81019e7d388c822b0b28af8d51c4622b83f1f0cb6fa3fc95e271226e43" BBCLASSEXTEND = "native"
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#241579): https://lists.openembedded.org/g/openembedded-core/message/241579 Mute This Topic: https://lists.openembedded.org/mt/120386222/21656 Group Owner: [email protected] Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [[email protected]] -=-=-=-=-=-=-=-=-=-=-=-
