Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package libXpm for openSUSE:Factory checked 
in at 2026-04-23 17:05:26
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libXpm (Old)
 and      /work/SRC/openSUSE:Factory/.libXpm.new.11940 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libXpm"

Thu Apr 23 17:05:26 2026 rev:19 rq:1348811 version:3.5.18

Changes:
--------
--- /work/SRC/openSUSE:Factory/libXpm/libXpm.changes    2026-01-28 
15:08:25.613192726 +0100
+++ /work/SRC/openSUSE:Factory/.libXpm.new.11940/libXpm.changes 2026-04-23 
17:09:22.980528416 +0200
@@ -1,0 +2,13 @@
+Wed Apr 22 15:22:16 UTC 2026 - Stefan Dirsch <[email protected]>
+
+- updated 0001-Fix-CVE-2026-4367-Out-of-bounds-read-in-xpmNextWord.patch
+  to the final version, which has been submitted to gitlab
+  (CVE-2026-4367, bsc#1260928, comment#22)
+
+-------------------------------------------------------------------
+Sat Mar 28 11:38:25 UTC 2026 - Stefan Dirsch <[email protected]>
+
+- 0001-Fix-CVE-2026-4367-Out-of-bounds-read-in-xpmNextWord.patch
+  * fix Out of bounds read (CVE-2026-4367, bsc#1260928)
+
+-------------------------------------------------------------------

New:
----
  0001-Fix-CVE-2026-4367-Out-of-bounds-read-in-xpmNextWord.patch

----------(New B)----------
  New:
- updated 0001-Fix-CVE-2026-4367-Out-of-bounds-read-in-xpmNextWord.patch
  to the final version, which has been submitted to gitlab
----------(New E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libXpm.spec ++++++
--- /var/tmp/diff_new_pack.EPOkf2/_old  2026-04-23 17:09:23.592553597 +0200
+++ /var/tmp/diff_new_pack.EPOkf2/_new  2026-04-23 17:09:23.592553597 +0200
@@ -30,6 +30,7 @@
 Source1:        
https://xorg.freedesktop.org/releases/individual/lib/%{name}-%{version}.tar.xz.sig
 Source2:        libXpm.keyring
 Source9:        baselibs.conf
+Patch0:         0001-Fix-CVE-2026-4367-Out-of-bounds-read-in-xpmNextWord.patch
 BuildRequires:  /usr/bin/gzip
 BuildRequires:  autoconf
 BuildRequires:  automake

++++++ 0001-Fix-CVE-2026-4367-Out-of-bounds-read-in-xpmNextWord.patch ++++++
>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] 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>
---
 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;
-- 
2.51.0

Reply via email to