Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package libX11 for openSUSE:Factory checked 
in at 2026-09-28 10:34:55
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libX11 (Old)
 and      /work/SRC/openSUSE:Factory/.libX11.new.383539 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libX11"

Mon Sep 28 10:34:55 2026 rev:62 rq:1380031 version:1.8.13

Changes:
--------
--- /work/SRC/openSUSE:Factory/libX11/libX11.changes    2026-09-21 
12:01:10.807108242 +0200
+++ /work/SRC/openSUSE:Factory/.libX11.new.383539/libX11.changes        
2026-09-28 10:34:58.874121583 +0200
@@ -1,0 +2,13 @@
+Wed Sep 23 18:17:41 UTC 2026 - Stefan Dirsch <[email protected]>
+
+- 
0001-1281653_CVE-2026-94283_ximcp-bound-XIM_OPEN_REPLY-attribute-lengths-to-the-.patch
+  * Out-of-bounds read vulnerability in libX11's XIM (X Input Method) 
attribute parser
+    (boo#1281653, CVE-2026-94283)
+- 
0002-1281657_CVE-2026-94284_ximcp-bound-XIM_REGISTER_TRIGGERKEYS-keylist-lengths.patch
+  * Out-of-bounds read vulnerability in libX11's XIM trigger-keyregistration 
parser.registration parser
+    (boo#1281657, CVE-2026-94284)
+- 
0003-1281661_CVE-2026-94285_lcGenConv-bound-byteM_parse_codeset-reads-to-remaini.patch
+  * Out-of-bounds read in libX11's byte-oriented codeset parser
+    (boo#1281661, CVE-2026-94285)
+
+-------------------------------------------------------------------

New:
----
  
0001-1281653_CVE-2026-94283_ximcp-bound-XIM_OPEN_REPLY-attribute-lengths-to-the-.patch
  
0002-1281657_CVE-2026-94284_ximcp-bound-XIM_REGISTER_TRIGGERKEYS-keylist-lengths.patch
  
0003-1281661_CVE-2026-94285_lcGenConv-bound-byteM_parse_codeset-reads-to-remaini.patch

----------(New B)----------
  New:
- 
0001-1281653_CVE-2026-94283_ximcp-bound-XIM_OPEN_REPLY-attribute-lengths-to-the-.patch
  * Out-of-bounds read vulnerability in libX11's XIM (X Input Method) attribute 
parser
  New:    (boo#1281653, CVE-2026-94283)
- 
0002-1281657_CVE-2026-94284_ximcp-bound-XIM_REGISTER_TRIGGERKEYS-keylist-lengths.patch
  * Out-of-bounds read vulnerability in libX11's XIM trigger-keyregistration 
parser.registration parser
  New:    (boo#1281657, CVE-2026-94284)
- 
0003-1281661_CVE-2026-94285_lcGenConv-bound-byteM_parse_codeset-reads-to-remaini.patch
  * Out-of-bounds read in libX11's byte-oriented codeset parser
----------(New E)----------

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

Other differences:
------------------
++++++ libX11.spec ++++++
--- /var/tmp/diff_new_pack.UNu4xL/_old  2026-09-28 10:34:59.536149320 +0200
+++ /var/tmp/diff_new_pack.UNu4xL/_new  2026-09-28 10:34:59.537149362 +0200
@@ -33,6 +33,9 @@
 Patch2:         en-locales.diff
 Patch3:         u_no-longer-crash-in-XVisualIDFromVisual.patch
 Patch4:         u_xkb-Check-the-keysym-range-in-_XkbReadKeyActions-CVE.patch
+Patch11:        
0001-1281653_CVE-2026-94283_ximcp-bound-XIM_OPEN_REPLY-attribute-lengths-to-the-.patch
+Patch12:        
0002-1281657_CVE-2026-94284_ximcp-bound-XIM_REGISTER_TRIGGERKEYS-keylist-lengths.patch
+Patch13:        
0003-1281661_CVE-2026-94285_lcGenConv-bound-byteM_parse_codeset-reads-to-remaini.patch
 BuildRequires:  fdupes
 BuildRequires:  libtool
 BuildRequires:  pkgconfig
@@ -123,6 +126,9 @@
 %patch -P 2
 %patch -P 3 -p1
 %patch -P 4 -p1
+%patch -P 11 -p1
+%patch -P 12 -p1
+%patch -P 13 -p1
 
 %build
 %configure \

++++++ 
0001-1281653_CVE-2026-94283_ximcp-bound-XIM_OPEN_REPLY-attribute-lengths-to-the-.patch
 ++++++
>From 42d0303f243002a9856c76060569a61893c670dd Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <[email protected]>
Date: Thu, 30 Jul 2026 09:51:54 +0200
Subject: [PATCH 1/3] ximcp: bound XIM_OPEN_REPLY attribute lengths to the
 received packet

_XimGetAttributeID() trusted the wire-embedded nBytesIMATTR /
nBytesICATTR values and per-attribute lengths from a malicious or
malformed XIM_OPEN_REPLY without comparing them to the actual number
of bytes returned by _XimRead().

That allows for potential out-of-bounds reads (and possible client
crashes) while parsing IM/IC attribute lists.

Pass the remaining OPEN_REPLY payload length from _XimOpen() via an
unused private field (now "open_attr_length") so that we can reject
nested totals that exceed that size, and compute padded attribute entry
sizes in a wide type so CARD16 wraparound cannot defeat the checks.

Found by AISLE in partnership with Red Hat

AISLE-Report-PSIRTSUPT-15963

CVE-2026-94283

Reported-by: Aisle Research
Co-authored-by: AI
Signed-off-by: Olivier Fourdan <[email protected]>
---
 modules/im/ximcp/imDefIm.c  |  9 +++++++++
 modules/im/ximcp/imRmAttr.c | 26 +++++++++++++++++++++++---
 src/xlibi18n/XimintP.h      |  2 +-
 3 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/modules/im/ximcp/imDefIm.c b/modules/im/ximcp/imDefIm.c
index b27f80c5..af1ac953 100644
--- a/modules/im/ximcp/imDefIm.c
+++ b/modules/im/ximcp/imDefIm.c
@@ -867,6 +867,15 @@ _XimOpen(
 
     im->private.proto.imid = buf_s[0];         /* imid */
 
+    if (len < (INT16)(XIM_HEADER_SIZE + sizeof(CARD16))) {
+       if(reply != preply)
+           Xfree(preply);
+       return False;
+    }
+    /* remaining OPEN_REPLY bytes after imid; read by _XimGetAttributeID */
+    im->private.proto.open_attr_length =
+       (CARD16)((size_t)len - XIM_HEADER_SIZE - sizeof(CARD16));
+
     if (!(_XimGetAttributeID(im, &buf_s[1]))) {
        if(reply != preply)
            Xfree(preply);
diff --git a/modules/im/ximcp/imRmAttr.c b/modules/im/ximcp/imRmAttr.c
index c56bd62e..e94421d9 100644
--- a/modules/im/ximcp/imRmAttr.c
+++ b/modules/im/ximcp/imRmAttr.c
@@ -1399,6 +1399,7 @@ _XimCountNumberOfAttr(
     unsigned int *names_len)
 {
     unsigned int n;
+    unsigned int entry_size;
     CARD16      len;
     CARD16      min_len = sizeof(CARD16)       /* sizeof attribute ID */
                         + sizeof(CARD16)       /* sizeof type of value */
@@ -1411,10 +1412,15 @@ _XimCountNumberOfAttr(
        if (len > (total - min_len)) {
            return 0;
        }
+       entry_size = (unsigned int)min_len + (unsigned int)len
+                  + (unsigned int)XIM_PAD(len + 2);
+
+       if (entry_size > total)
+           return 0;
+
        *names_len += (len + 1);
-       len += (min_len + XIM_PAD(len + 2));
-       total -= len;
-       attr = (CARD16 *)((char *)attr + len);
+       total -= entry_size;
+       attr = (CARD16 *)((char *)attr + entry_size);
        n++;
     }
     return n;
@@ -1433,6 +1439,8 @@ _XimGetAttributeID(
     char               **values;
     register int         i;
     CARD16               len;
+    CARD16              *buf_s = buf;
+    size_t               remain = (size_t)im->private.proto.open_attr_length;
     CARD16               min_len = sizeof(CARD16) /* sizeof attribute ID */
                                  + sizeof(CARD16) /* sizeof type of value */
                                  + sizeof(INT16); /* sizeof length of attr */
@@ -1440,6 +1448,10 @@ _XimGetAttributeID(
      * IM attribute ID
      */
 
+    if (remain < sizeof(CARD16) ||
+       (size_t)buf[0] > remain - sizeof(CARD16))
+       return False;
+
     if (!(n = _XimCountNumberOfAttr(buf[0], &buf[1], &names_len)))
        return False;
 
@@ -1484,6 +1496,14 @@ _XimGetAttributeID(
     /*
      * IC attribute ID
      */
+    remain -= sizeof(CARD16) + (size_t)buf_s[0];
+    buf = (CARD16 *)((char *)(buf_s + 1) + buf_s[0]);
+
+    if (remain < (2 * sizeof(CARD16)))
+       return False;
+
+    if ((size_t)buf[0] > remain - (2 * sizeof(CARD16)))
+       return False;
 
     if (!(n = _XimCountNumberOfAttr(buf[0], &buf[2], &names_len)))
        return False;
diff --git a/src/xlibi18n/XimintP.h b/src/xlibi18n/XimintP.h
index 2957e3a0..efe8bb8c 100644
--- a/src/xlibi18n/XimintP.h
+++ b/src/xlibi18n/XimintP.h
@@ -115,7 +115,7 @@ typedef struct _XimProtoPrivateRec {
 
     Window                      im_window;
     XIMID                       imid;
-    CARD16                      unused;
+    CARD16                      open_attr_length;
     XIMStyles                  *default_styles;
     CARD32                     *im_onkeylist;
     CARD32                     *im_offkeylist;
-- 
2.51.0


++++++ 
0002-1281657_CVE-2026-94284_ximcp-bound-XIM_REGISTER_TRIGGERKEYS-keylist-lengths.patch
 ++++++
>From 1b7904002d212eed40949ccf4e8e7156f9fec0e2 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <[email protected]>
Date: Thu, 30 Jul 2026 16:32:10 +0200
Subject: [PATCH 2/3] ximcp: bound XIM_REGISTER_TRIGGERKEYS keylist lengths to
 the packet

_XimRegisterTriggerKeysCallback() receives the full packet length from
the transport but did not pass it to _XimRegisterTriggerkey(), which
trusted the wire CARD32 on-keys and off-keys length fields for Xmalloc
and memcpy.

A malicious XIM_REGISTER_TRIGGERKEYS message with a valid outer frame
but oversized inner lengths can therefore cause an out-of-bounds read
and crash the client.

Pass the remaining payload size into the static helper and reject
on-keys/off-keys lengths that do not fit before copying.

Found by AISLE in partnership with Red Hat

AISLE-Report-PSIRTSUPT-16671

CVE-2026-94284

Reported-by: Aisle Research
Co-authored-by: AI
Signed-off-by: Olivier Fourdan <[email protected]>
---
 modules/im/ximcp/imDefLkup.c | 29 ++++++++++++++++++++---------
 1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/modules/im/ximcp/imDefLkup.c b/modules/im/ximcp/imDefLkup.c
index f5ba3405..b2b9d784 100644
--- a/modules/im/ximcp/imDefLkup.c
+++ b/modules/im/ximcp/imDefLkup.c
@@ -498,10 +498,12 @@ _XimForwardEventCallback(
 static Bool
 _XimRegisterTriggerkey(
     Xim                         im,
-    XPointer            buf)
+    XPointer            buf,
+    size_t              buf_len)
 {
     CARD32             *buf_l = (CARD32 *)buf;
-    CARD32              len;
+    size_t              len;
+    size_t              remaining;
     CARD32             *key;
 
     if (IS_DYNAMIC_EVENT_FLOW(im))     /* already Dynamic event flow mode */
@@ -510,9 +512,11 @@ _XimRegisterTriggerkey(
     /*
      *  register onkeylist
      */
-
-    len = buf_l[0];                            /* length of on-keys */
-    len += sizeof(INT32);                      /* sizeof length of on-keys */
+    if (buf_len < sizeof(CARD32))
+       return False;
+    if ((size_t)buf_l[0] > buf_len - sizeof(CARD32))
+       return False;
+    len = (size_t)buf_l[0] + sizeof(CARD32);
 
     if (!(key = Xmalloc(len))) {
        _XimError(im, 0, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
@@ -526,10 +530,13 @@ _XimRegisterTriggerkey(
     /*
      *  register offkeylist
      */
-
+    remaining = buf_len - len;
+    if (remaining < sizeof(CARD32))
+       return False;
     buf_l = (CARD32 *)((char *)buf + len);
-    len = buf_l[0];                            /* length of off-keys */
-    len += sizeof(INT32);                      /* sizeof length of off-keys */
+    if ((size_t)buf_l[0] > remaining - sizeof(CARD32))
+       return False;
+    len = (size_t)buf_l[0] + sizeof(CARD32);
 
     if (!(key = Xmalloc(len))) {
        _XimError(im, 0, XIM_BadAlloc, (INT16)0, (CARD16)0, (char *)NULL);
@@ -551,8 +558,12 @@ _XimRegisterTriggerKeysCallback(
 {
     CARD16     *buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
     Xim                 im = (Xim)call_data;
+    size_t      payload_len;
 
-    (void )_XimRegisterTriggerkey(im, (XPointer)&buf_s[2]);
+    if (len < (INT16)(XIM_HEADER_SIZE + 2 * sizeof(CARD16)))
+       return True;
+    payload_len = (size_t)len - XIM_HEADER_SIZE - 2 * sizeof(CARD16);
+    (void)_XimRegisterTriggerkey(im, (XPointer)&buf_s[2], payload_len);
     return True;
 }
 
-- 
2.51.0


++++++ 
0003-1281661_CVE-2026-94285_lcGenConv-bound-byteM_parse_codeset-reads-to-remaini.patch
 ++++++
>From 980868483446f24f9658d26aa5bfa42f3da6dd3a Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <[email protected]>
Date: Fri, 11 Sep 2026 16:02:06 +0200
Subject: [PATCH 3/3] lcGenConv: bound byteM_parse_codeset() reads to remaining
 input length

byteM_parse_codeset() walks candidate byte-oriented codesets and
dereferences input bytes up to codeset->length, but it does not
receive the remaining input length and does not check whether enough
bytes are available before reading.

When the last available byte is a valid lead byte for a multi-byte
codeset (e.g. GBK, Big5), the function reads one byte past the
caller-provided buffer while matching the second byte range.

Pass the remaining byte count into byteM_parse_codeset() and skip
candidate codesets whose length exceeds the available input.

Found by AISLE in partnership with Red Hat

AISLE-Report-PSIRTSUPT-16718

CVE-2026-94285

Reported-by: Aisle Research
Assisted-by: AI
Signed-off-by: Olivier Fourdan <[email protected]>
---
 modules/lc/gen/lcGenConv.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/modules/lc/gen/lcGenConv.c b/modules/lc/gen/lcGenConv.c
index e1a13a28..7ba75946 100644
--- a/modules/lc/gen/lcGenConv.c
+++ b/modules/lc/gen/lcGenConv.c
@@ -321,7 +321,8 @@ mb_parse_codeset(
 static CodeSet
 byteM_parse_codeset(
     XLCd lcd,
-    const char *inbufptr)
+    const char *inbufptr,
+    int remaining_bytes)
 {
     unsigned char ch;
     CodeSet codeset;
@@ -340,6 +341,8 @@ byteM_parse_codeset(
         byteM = codeset->byteM;
         if (codeset->side != XlcNONE || byteM == NULL)
            continue;
+        if (codeset->length > remaining_bytes)
+           continue;
 
         for (j = 0; j < codeset->length; j++) {
            ch = *((const unsigned char *)(inbufptr + j));
@@ -800,7 +803,7 @@ mbstowcs_org(
         }
 
        /* next mb char data for byteM ? */
-       if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1))))
+       if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1), (*from_left) + 
1)))
            goto next_mb_char;
 
        /* next mb char data for GL or GR side ? */
@@ -1691,7 +1694,7 @@ mbstostr(
         }
 
        /* next char data : byteM ? */
-       if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1))))
+       if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1), (*from_left) + 
1)))
            goto next_mb_char;
 
        /* next char data : GL or GR side ? */
@@ -1802,7 +1805,7 @@ mbtocs(
         }
 
        /* next mb char data for byteM ? */
-       if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1))))
+       if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1), (*from_left) + 
1)))
            goto next_mb_char;
 
        /* next mb char data for GL or GR side ? */
-- 
2.51.0

Reply via email to