diff --git a/SOURCES/0001-Cursor-Refuse-to-free-the-root-cursor.patch b/SOURCES/0001-Cursor-Refuse-to-free-the-root-cursor.patch new file mode 100644 index 0000000..7b6027c --- /dev/null +++ b/SOURCES/0001-Cursor-Refuse-to-free-the-root-cursor.patch @@ -0,0 +1,55 @@ +From 42ec29c7fbf8dc797c369d5fe0e4f2e20725332b Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Wed, 27 Nov 2024 11:27:05 +0100 +Subject: [PATCH xserver 01/13] Cursor: Refuse to free the root cursor +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If a cursor reference count drops to 0, the cursor is freed. + +The root cursor however is referenced with a specific global variable, +and when the root cursor is freed, the global variable may still point +to freed memory. + +Make sure to prevent the rootCursor from being explicitly freed by a +client. + +CVE-2025-26594, ZDI-CAN-25544 + +This vulnerability was discovered by: +Jan-Niklas Sohn working with Trend Micro Zero Day Initiative + +v2: Explicitly forbid XFreeCursor() on the root cursor (Peter Hutterer +) +v3: Return BadCursor instead of BadValue (Michel Dänzer +) + +Signed-off-by: Olivier Fourdan +Suggested-by: Peter Hutterer +Reviewed-by: Peter Hutterer +(cherry picked from commit 01642f263f12becf803b19be4db95a4a83f94acc) + +Part-of: +--- + dix/dispatch.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/dix/dispatch.c b/dix/dispatch.c +index a33bfaa9e..9654c207e 100644 +--- a/dix/dispatch.c ++++ b/dix/dispatch.c +@@ -3039,6 +3039,10 @@ ProcFreeCursor(ClientPtr client) + rc = dixLookupResourceByType((void **) &pCursor, stuff->id, RT_CURSOR, + client, DixDestroyAccess); + if (rc == Success) { ++ if (pCursor == rootCursor) { ++ client->errorValue = stuff->id; ++ return BadCursor; ++ } + FreeResource(stuff->id, RT_NONE); + return Success; + } +-- +2.48.1 + diff --git a/SOURCES/0001-Xi-ProcXIGetSelectedEvents-needs-to-use-unswapped-le.patch b/SOURCES/0001-Xi-ProcXIGetSelectedEvents-needs-to-use-unswapped-le.patch new file mode 100644 index 0000000..5a64c75 --- /dev/null +++ b/SOURCES/0001-Xi-ProcXIGetSelectedEvents-needs-to-use-unswapped-le.patch @@ -0,0 +1,45 @@ +From 96798fc1967491c80a4d0c8d9e0a80586cb2152b Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Fri, 22 Mar 2024 18:51:45 -0700 +Subject: [PATCH 1/4] Xi: ProcXIGetSelectedEvents needs to use unswapped length + to send reply + +CVE-2024-31080 + +Reported-by: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=69762 +Fixes: 53e821ab4 ("Xi: add request processing for XIGetSelectedEvents.") +Signed-off-by: Alan Coopersmith +Part-of: +--- + Xi/xiselectev.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/Xi/xiselectev.c b/Xi/xiselectev.c +index edcb8a0d3..ac1494987 100644 +--- a/Xi/xiselectev.c ++++ b/Xi/xiselectev.c +@@ -349,6 +349,7 @@ ProcXIGetSelectedEvents(ClientPtr client) + InputClientsPtr others = NULL; + xXIEventMask *evmask = NULL; + DeviceIntPtr dev; ++ uint32_t length; + + REQUEST(xXIGetSelectedEventsReq); + REQUEST_SIZE_MATCH(xXIGetSelectedEventsReq); +@@ -418,10 +419,12 @@ ProcXIGetSelectedEvents(ClientPtr client) + } + } + ++ /* save the value before SRepXIGetSelectedEvents swaps it */ ++ length = reply.length; + WriteReplyToClient(client, sizeof(xXIGetSelectedEventsReply), &reply); + + if (reply.num_masks) +- WriteToClient(client, reply.length * 4, buffer); ++ WriteToClient(client, length * 4, buffer); + + free(buffer); + return Success; +-- +2.44.0 + diff --git a/SOURCES/0001-dix-Force-update-LEDs-after-device-state-update-in-E.patch b/SOURCES/0001-dix-Force-update-LEDs-after-device-state-update-in-E.patch new file mode 100644 index 0000000..a315373 --- /dev/null +++ b/SOURCES/0001-dix-Force-update-LEDs-after-device-state-update-in-E.patch @@ -0,0 +1,101 @@ +From 9c27c756438a62fdd768147d753b4c5fc731247b Mon Sep 17 00:00:00 2001 +From: Yao Wei +Date: Tue, 21 Feb 2023 03:43:05 +0000 +Subject: [PATCH xserver] dix: Force update LEDs after device state update in + EnableDevice +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is to make sure the hardware gets the device states regardless +whether the internal state has changed or not, to overcome situations +that device LEDs are out of sync e.g. switching between VTs. + +Signed-off-by: Yao Wei (魏銘廷) +(cherry picked from commit 7ce57e179b257f35e447971f4fb6614e3360762a) +--- + dix/devices.c | 4 ++++ + include/xkbsrv.h | 2 ++ + xkb/xkbLEDs.c | 38 ++++++++++++++++++++++++++++++++++++++ + 3 files changed, 44 insertions(+) + +diff --git a/dix/devices.c b/dix/devices.c +index 00c453980..5629d9cf1 100644 +--- a/dix/devices.c ++++ b/dix/devices.c +@@ -426,6 +426,10 @@ EnableDevice(DeviceIntPtr dev, BOOL sendevent) + + if (!IsMaster(dev) && !IsFloating(dev)) + XkbPushLockedStateToSlaves(GetMaster(dev, MASTER_KEYBOARD), 0, 0); ++ ++ /* Now make sure our LEDs are in sync with the locked state */ ++ XkbForceUpdateDeviceLEDs(dev); ++ + RecalculateMasterButtons(dev); + + /* initialise an idle timer for this device*/ +diff --git a/include/xkbsrv.h b/include/xkbsrv.h +index fbb5427e1..90a5e5327 100644 +--- a/include/xkbsrv.h ++++ b/include/xkbsrv.h +@@ -505,6 +505,8 @@ extern _X_EXPORT void XkbUpdateIndicators(DeviceIntPtr /* keybd */ , + XkbEventCausePtr /* cause */ + ); + ++extern void XkbForceUpdateDeviceLEDs(DeviceIntPtr /* keybd */); ++ + extern _X_EXPORT void XkbUpdateAllDeviceIndicators(XkbChangesPtr /* changes */, + XkbEventCausePtr /* cause */ + ); +diff --git a/xkb/xkbLEDs.c b/xkb/xkbLEDs.c +index 5792d9fb7..3fb8fc526 100644 +--- a/xkb/xkbLEDs.c ++++ b/xkb/xkbLEDs.c +@@ -435,6 +435,44 @@ XkbUpdateIndicators(DeviceIntPtr dev, + + /***====================================================================***/ + ++ /* ++ * void ++ * XkbForceUpdateDeviceLEDs(DeviceIntPtr dev) ++ * ++ * Force update LED states to the hardware from the device state ++ * specified by 'dev'. ++ * ++ * If 'dev' is a master device, this function will also force update ++ * its slave devices. ++ * ++ * Used if the actual LED state was externally set and need to push ++ * current state to the hardware e.g. switching between VTs. ++ */ ++ ++void ++XkbForceUpdateDeviceLEDs(DeviceIntPtr dev) ++{ ++ DeviceIntPtr master; ++ XkbSrvLedInfoPtr sli; ++ ++ if (!dev->key) ++ return; ++ ++ sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 0); ++ XkbDDXUpdateDeviceIndicators(dev, sli, sli->effectiveState); ++ ++ if (IsMaster(dev)) { ++ master = dev; ++ nt_list_for_each_entry(dev, inputInfo.devices, next) { ++ if (!dev->key || GetMaster(dev, MASTER_KEYBOARD) != master) ++ continue; ++ ++ sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 0); ++ XkbDDXUpdateDeviceIndicators(dev, sli, sli->effectiveState); ++ } ++ } ++} ++ + /***====================================================================***/ + + /* +-- +2.48.1 + diff --git a/SOURCES/0001-dix-fix-valuator-copy-paste-error-in-the-DeviceState.patch b/SOURCES/0001-dix-fix-valuator-copy-paste-error-in-the-DeviceState.patch new file mode 100644 index 0000000..363af1f --- /dev/null +++ b/SOURCES/0001-dix-fix-valuator-copy-paste-error-in-the-DeviceState.patch @@ -0,0 +1,33 @@ +From 133e0d651c5d12bf01999d6289e84e224ba77adc Mon Sep 17 00:00:00 2001 +From: Peter Hutterer +Date: Mon, 22 Jan 2024 14:22:12 +1000 +Subject: [PATCH] dix: fix valuator copy/paste error in the DeviceStateNotify + event + +Fixes 219c54b8a3337456ce5270ded6a67bcde53553d5 +--- + dix/enterleave.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/dix/enterleave.c b/dix/enterleave.c +index 7b7ba1098..c1e6ac600 100644 +--- a/dix/enterleave.c ++++ b/dix/enterleave.c +@@ -619,11 +619,11 @@ FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v, + ev->first_valuator = first; + switch (ev->num_valuators) { + case 6: +- ev->valuator2 = v->axisVal[first + 5]; ++ ev->valuator5 = v->axisVal[first + 5]; + case 5: +- ev->valuator2 = v->axisVal[first + 4]; ++ ev->valuator4 = v->axisVal[first + 4]; + case 4: +- ev->valuator2 = v->axisVal[first + 3]; ++ ev->valuator3 = v->axisVal[first + 3]; + case 3: + ev->valuator2 = v->axisVal[first + 2]; + case 2: +-- +2.44.0 + diff --git a/SOURCES/0001-ephyr-Fix-incompatible-pointer-type-build-error.patch b/SOURCES/0001-ephyr-Fix-incompatible-pointer-type-build-error.patch new file mode 100644 index 0000000..345e660 --- /dev/null +++ b/SOURCES/0001-ephyr-Fix-incompatible-pointer-type-build-error.patch @@ -0,0 +1,54 @@ +From e89edec497bac581ca9b614fb00c25365580f045 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= +Date: Fri, 19 Jan 2024 13:05:51 +0100 +Subject: [PATCH] ephyr: Fix incompatible pointer type build error +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fix a compilation error on 32 bits architectures with gcc 14: + + ephyr_glamor_xv.c: In function ‘ephyr_glamor_xv_init’: + ephyr_glamor_xv.c:154:31: error: assignment to ‘SetPortAttributeFuncPtr’ {aka ‘int (*)(struct _KdScreenInfo *, long unsigned int, int, void *)’} from incompatible pointer type ‘int (*)(KdScreenInfo *, Atom, INT32, void *)’ {aka ‘int (*)(struct _KdScreenInfo *, long unsigned int, long int, void *)’} [-Wincompatible-pointer-types] + 154 | adaptor->SetPortAttribute = ephyr_glamor_xv_set_port_attribute; + | ^ + ephyr_glamor_xv.c:155:31: error: assignment to ‘GetPortAttributeFuncPtr’ {aka ‘int (*)(struct _KdScreenInfo *, long unsigned int, int *, void *)’} from incompatible pointer type ‘int (*)(KdScreenInfo *, Atom, INT32 *, void *)’ {aka ‘int (*)(struct _KdScreenInfo *, long unsigned int, long int *, void *)’} [-Wincompatible-pointer-types] + 155 | adaptor->GetPortAttribute = ephyr_glamor_xv_get_port_attribute; + | ^ + +Build error logs: +https://koji.fedoraproject.org/koji/taskinfo?taskID=111964273 + +Signed-off-by: José Expósito +--- + hw/kdrive/ephyr/ephyr_glamor_xv.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/hw/kdrive/ephyr/ephyr_glamor_xv.c b/hw/kdrive/ephyr/ephyr_glamor_xv.c +index 4dd15cf41..b5eae48c8 100644 +--- a/hw/kdrive/ephyr/ephyr_glamor_xv.c ++++ b/hw/kdrive/ephyr/ephyr_glamor_xv.c +@@ -50,16 +50,16 @@ ephyr_glamor_xv_stop_video(KdScreenInfo *screen, void *data, Bool cleanup) + + static int + ephyr_glamor_xv_set_port_attribute(KdScreenInfo *screen, +- Atom attribute, INT32 value, void *data) ++ Atom attribute, int value, void *data) + { +- return glamor_xv_set_port_attribute(data, attribute, value); ++ return glamor_xv_set_port_attribute(data, attribute, (INT32)value); + } + + static int + ephyr_glamor_xv_get_port_attribute(KdScreenInfo *screen, +- Atom attribute, INT32 *value, void *data) ++ Atom attribute, int *value, void *data) + { +- return glamor_xv_get_port_attribute(data, attribute, value); ++ return glamor_xv_get_port_attribute(data, attribute, (INT32 *)value); + } + + static void +-- +2.43.0 + diff --git a/SOURCES/0001-render-Avoid-0-or-less-animated-cursors.patch b/SOURCES/0001-render-Avoid-0-or-less-animated-cursors.patch new file mode 100644 index 0000000..edd66c6 --- /dev/null +++ b/SOURCES/0001-render-Avoid-0-or-less-animated-cursors.patch @@ -0,0 +1,89 @@ +From 4c8e10312a721aa2f36048388284a2fd4ad97043 Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Fri, 28 Mar 2025 09:43:52 +0100 +Subject: [PATCH xserver 1/7] render: Avoid 0 or less animated cursors +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Animated cursors use a series of cursors that the client can set. + +By default, the Xserver assumes at least one cursor is specified +while a client may actually pass no cursor at all. + +That causes an out-of-bound read creating the animated cursor and a +crash of the Xserver: + + | Invalid read of size 8 + | at 0x5323F4: AnimCursorCreate (animcur.c:325) + | by 0x52D4C5: ProcRenderCreateAnimCursor (render.c:1817) + | by 0x52DC80: ProcRenderDispatch (render.c:1999) + | by 0x4A1E9D: Dispatch (dispatch.c:560) + | by 0x4B0169: dix_main (main.c:284) + | by 0x4287F5: main (stubmain.c:34) + | Address 0x59aa010 is 0 bytes after a block of size 0 alloc'd + | at 0x48468D3: reallocarray (vg_replace_malloc.c:1803) + | by 0x52D3DA: ProcRenderCreateAnimCursor (render.c:1802) + | by 0x52DC80: ProcRenderDispatch (render.c:1999) + | by 0x4A1E9D: Dispatch (dispatch.c:560) + | by 0x4B0169: dix_main (main.c:284) + | by 0x4287F5: main (stubmain.c:34) + | + | Invalid read of size 2 + | at 0x5323F7: AnimCursorCreate (animcur.c:325) + | by 0x52D4C5: ProcRenderCreateAnimCursor (render.c:1817) + | by 0x52DC80: ProcRenderDispatch (render.c:1999) + | by 0x4A1E9D: Dispatch (dispatch.c:560) + | by 0x4B0169: dix_main (main.c:284) + | by 0x4287F5: main (stubmain.c:34) + | Address 0x8 is not stack'd, malloc'd or (recently) free'd + +To avoid the issue, check the number of cursors specified and return a +BadValue error in both the proc handler (early) and the animated cursor +creation (as this is a public function) if there is 0 or less cursor. + +CVE-2025-49175 + +This issue was discovered by Nils Emmerich and +reported by Julian Suleder via ERNW Vulnerability Disclosure. + +Signed-off-by: Olivier Fourdan +Reviewed-by: José Expósito +(cherry picked from commit 0885e0b26225c90534642fe911632ec0779eebee) + +Part-of: +--- + render/animcur.c | 3 +++ + render/render.c | 2 ++ + 2 files changed, 5 insertions(+) + +diff --git a/render/animcur.c b/render/animcur.c +index ef27bda27..77942d846 100644 +--- a/render/animcur.c ++++ b/render/animcur.c +@@ -304,6 +304,9 @@ AnimCursorCreate(CursorPtr *cursors, CARD32 *deltas, int ncursor, + int rc = BadAlloc, i; + AnimCurPtr ac; + ++ if (ncursor <= 0) ++ return BadValue; ++ + for (i = 0; i < screenInfo.numScreens; i++) + if (!GetAnimCurScreen(screenInfo.screens[i])) + return BadImplementation; +diff --git a/render/render.c b/render/render.c +index 456f156d4..e9bbac62d 100644 +--- a/render/render.c ++++ b/render/render.c +@@ -1788,6 +1788,8 @@ ProcRenderCreateAnimCursor(ClientPtr client) + ncursor = + (client->req_len - + (bytes_to_int32(sizeof(xRenderCreateAnimCursorReq)))) >> 1; ++ if (ncursor <= 0) ++ return BadValue; + cursors = xallocarray(ncursor, sizeof(CursorPtr) + sizeof(CARD32)); + if (!cursors) + return BadAlloc; +-- +2.49.0 + diff --git a/SOURCES/0001-render-Avoid-possible-double-free-in-ProcRenderAddGl.patch b/SOURCES/0001-render-Avoid-possible-double-free-in-ProcRenderAddGl.patch new file mode 100644 index 0000000..549f90a --- /dev/null +++ b/SOURCES/0001-render-Avoid-possible-double-free-in-ProcRenderAddGl.patch @@ -0,0 +1,72 @@ +From 337d8d48b618d4fc0168a7b978be4c3447650b04 Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Fri, 5 Apr 2024 15:24:49 +0200 +Subject: [PATCH] render: Avoid possible double-free in ProcRenderAddGlyphs() + +ProcRenderAddGlyphs() adds the glyph to the glyphset using AddGlyph() and +then frees it using FreeGlyph() to decrease the reference count, after +AddGlyph() has increased it. + +AddGlyph() however may chose to reuse an existing glyph if it's already +in the glyphSet, and free the glyph that was given, in which case the +caller function, ProcRenderAddGlyphs() will call FreeGlyph() on an +already freed glyph, as reported by ASan: + + READ of size 4 thread T0 + #0 in FreeGlyph xserver/render/glyph.c:252 + #1 in ProcRenderAddGlyphs xserver/render/render.c:1174 + #2 in Dispatch xserver/dix/dispatch.c:546 + #3 in dix_main xserver/dix/main.c:271 + #4 in main xserver/dix/stubmain.c:34 + #5 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 + #6 in __libc_start_main_impl ../csu/libc-start.c:360 + #7 (/usr/bin/Xwayland+0x44fe4) + Address is located 0 bytes inside of 64-byte region + freed by thread T0 here: + #0 in __interceptor_free libsanitizer/asan/asan_malloc_linux.cpp:52 + #1 in _dixFreeObjectWithPrivates xserver/dix/privates.c:538 + #2 in AddGlyph xserver/render/glyph.c:295 + #3 in ProcRenderAddGlyphs xserver/render/render.c:1173 + #4 in Dispatch xserver/dix/dispatch.c:546 + #5 in dix_main xserver/dix/main.c:271 + #6 in main xserver/dix/stubmain.c:34 + #7 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 + previously allocated by thread T0 here: + #0 in __interceptor_malloc libsanitizer/asan/asan_malloc_linux.cpp:69 + #1 in AllocateGlyph xserver/render/glyph.c:355 + #2 in ProcRenderAddGlyphs xserver/render/render.c:1085 + #3 in Dispatch xserver/dix/dispatch.c:546 + #4 in dix_main xserver/dix/main.c:271 + #5 in main xserver/dix/stubmain.c:34 + #6 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 + SUMMARY: AddressSanitizer: heap-use-after-free xserver/render/glyph.c:252 in FreeGlyph + +To avoid that, make sure not to free the given glyph in AddGlyph(). + +v2: Simplify the test using the boolean returned from AddGlyph() (Michel) +v3: Simplify even more by not freeing the glyph in AddGlyph() (Peter) + +Fixes: bdca6c3d1 - render: fix refcounting of glyphs during ProcRenderAddGlyphs +Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1659 +Signed-off-by: Olivier Fourdan +Part-of: +--- + render/glyph.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/render/glyph.c b/render/glyph.c +index 13991f8a1..5fa7f3b5b 100644 +--- a/render/glyph.c ++++ b/render/glyph.c +@@ -291,8 +291,6 @@ AddGlyph(GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id) + gr = FindGlyphRef(&globalGlyphs[glyphSet->fdepth], signature, + TRUE, glyph->sha1); + if (gr->glyph && gr->glyph != DeletedGlyph && gr->glyph != glyph) { +- FreeGlyphPicture(glyph); +- dixFreeObjectWithPrivates(glyph, PRIVATE_GLYPH); + glyph = gr->glyph; + } + else if (gr->glyph != glyph) { +-- +2.44.0 + diff --git a/SOURCES/0001-xfree86-Fix-potentially-NULL-reference-to-platform-d.patch b/SOURCES/0001-xfree86-Fix-potentially-NULL-reference-to-platform-d.patch new file mode 100644 index 0000000..b67ed88 --- /dev/null +++ b/SOURCES/0001-xfree86-Fix-potentially-NULL-reference-to-platform-d.patch @@ -0,0 +1,63 @@ +From 0d93bbfa2cfacbb73741f8bed0e32fa1a656b928 Mon Sep 17 00:00:00 2001 +From: Povilas Kanapickas +Date: Fri, 26 Mar 2021 00:51:02 +0200 +Subject: [PATCH xserver] xfree86: Fix potentially NULL reference to platform + device's PCI device +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +xf86_platform_devices[i].pdev may be NULL in cases we fail to parse the +busid in config_udev_odev_setup_attribs() (see also [1], [2]) such as +when udev does not give use ID_PATH. This in turn leads to +platform_find_pci_info() being not called and pdev being NULL. + +[1]: https://gitlab.freedesktop.org/xorg/xserver/-/issues/993 +[2]: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1076 + +Reviewed-by: Zoltán Böszörményi +Signed-off-by: Povilas Kanapickas +Signed-off-by: Michel Dänzer +--- + hw/xfree86/common/xf86platformBus.c | 10 ++++++---- + hw/xfree86/os-support/linux/lnx_platform.c | 3 +++ + 2 files changed, 9 insertions(+), 4 deletions(-) + +diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c +index ee2f3f86a..e43ff69af 100644 +--- a/hw/xfree86/common/xf86platformBus.c ++++ b/hw/xfree86/common/xf86platformBus.c +@@ -365,10 +365,12 @@ xf86MergeOutputClassOptions(int entityIndex, void **options) + break; + case BUS_PCI: + for (i = 0; i < xf86_num_platform_devices; i++) { +- if (MATCH_PCI_DEVICES(xf86_platform_devices[i].pdev, +- entity->bus.id.pci)) { +- dev = &xf86_platform_devices[i]; +- break; ++ if (xf86_platform_devices[i].pdev) { ++ if (MATCH_PCI_DEVICES(xf86_platform_devices[i].pdev, ++ entity->bus.id.pci)) { ++ dev = &xf86_platform_devices[i]; ++ break; ++ } + } + } + break; +diff --git a/hw/xfree86/os-support/linux/lnx_platform.c b/hw/xfree86/os-support/linux/lnx_platform.c +index fe2142182..8a6be97aa 100644 +--- a/hw/xfree86/os-support/linux/lnx_platform.c ++++ b/hw/xfree86/os-support/linux/lnx_platform.c +@@ -85,6 +85,9 @@ xf86PlatformDeviceCheckBusID(struct xf86_platform_device *device, const char *bu + bustype = StringToBusType(busid, &id); + if (bustype == BUS_PCI) { + struct pci_device *pPci = device->pdev; ++ if (!pPci) ++ return FALSE; ++ + if (xf86ComparePciBusString(busid, + ((pPci->domain << 8) + | pPci->bus), +-- +2.49.0 + diff --git a/SOURCES/0001-xkb-Fix-buffer-overflow-in-_XkbSetCompatMap.patch b/SOURCES/0001-xkb-Fix-buffer-overflow-in-_XkbSetCompatMap.patch new file mode 100644 index 0000000..2db1508 --- /dev/null +++ b/SOURCES/0001-xkb-Fix-buffer-overflow-in-_XkbSetCompatMap.patch @@ -0,0 +1,54 @@ +From 56351307017e2501f7cd6e31efcfb55c19aba75a Mon Sep 17 00:00:00 2001 +From: Matthieu Herrb +Date: Thu, 10 Oct 2024 10:37:28 +0200 +Subject: [PATCH] xkb: Fix buffer overflow in _XkbSetCompatMap() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The _XkbSetCompatMap() function attempts to resize the `sym_interpret` +buffer. + +However, It didn't update its size properly. It updated `num_si` only, +without updating `size_si`. + +This may lead to local privilege escalation if the server is run as root +or remote code execution (e.g. x11 over ssh). + +CVE-2024-9632, ZDI-CAN-24756 + +This vulnerability was discovered by: +Jan-Niklas Sohn working with Trend Micro Zero Day Initiative + +Reviewed-by: Peter Hutterer +Tested-by: Peter Hutterer +Reviewed-by: José Expósito +--- + xkb/xkb.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/xkb/xkb.c b/xkb/xkb.c +index f203270d5..70e8279aa 100644 +--- a/xkb/xkb.c ++++ b/xkb/xkb.c +@@ -2991,13 +2991,13 @@ _XkbSetCompatMap(ClientPtr client, DeviceIntPtr dev, + XkbSymInterpretPtr sym; + unsigned int skipped = 0; + +- if ((unsigned) (req->firstSI + req->nSI) > compat->num_si) { +- compat->num_si = req->firstSI + req->nSI; ++ if ((unsigned) (req->firstSI + req->nSI) > compat->size_si) { ++ compat->num_si = compat->size_si = req->firstSI + req->nSI; + compat->sym_interpret = reallocarray(compat->sym_interpret, +- compat->num_si, ++ compat->size_si, + sizeof(XkbSymInterpretRec)); + if (!compat->sym_interpret) { +- compat->num_si = 0; ++ compat->num_si = compat->size_si = 0; + return BadAlloc; + } + } +-- +2.46.2 + diff --git a/SOURCES/0001-xquartz-Remove-invalid-Unicode-sequence.patch b/SOURCES/0001-xquartz-Remove-invalid-Unicode-sequence.patch new file mode 100644 index 0000000..926849e --- /dev/null +++ b/SOURCES/0001-xquartz-Remove-invalid-Unicode-sequence.patch @@ -0,0 +1,30 @@ +From a7ba1e9fe41019296a0f3ddff3d681f77e041ad7 Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Tue, 7 May 2024 18:04:02 +0200 +Subject: [PATCH] xquartz: Remove invalid Unicode sequence + +This is flagged by the automatic scanning tools. + +Signed-off-by: Olivier Fourdan +Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1673 +Part-of: +--- + hw/xquartz/bundle/Resources/he.lproj/main.nib/designable.nib | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/xquartz/bundle/Resources/he.lproj/main.nib/designable.nib b/hw/xquartz/bundle/Resources/he.lproj/main.nib/designable.nib +index e56c1adbc..42042a18d 100644 +--- a/hw/xquartz/bundle/Resources/he.lproj/main.nib/designable.nib ++++ b/hw/xquartz/bundle/Resources/he.lproj/main.nib/designable.nib +@@ -438,7 +438,7 @@ + + + +- ++ + + + +-- +2.45.0 + diff --git a/SOURCES/0002-Xi-ProcXIPassiveGrabDevice-needs-to-use-unswapped-le.patch b/SOURCES/0002-Xi-ProcXIPassiveGrabDevice-needs-to-use-unswapped-le.patch new file mode 100644 index 0000000..4e061f7 --- /dev/null +++ b/SOURCES/0002-Xi-ProcXIPassiveGrabDevice-needs-to-use-unswapped-le.patch @@ -0,0 +1,43 @@ +From 3e77295f888c67fc7645db5d0c00926a29ffecee Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Fri, 22 Mar 2024 18:56:27 -0700 +Subject: [PATCH 2/4] Xi: ProcXIPassiveGrabDevice needs to use unswapped length + to send reply + +CVE-2024-31081 + +Fixes: d220d6907 ("Xi: add GrabButton and GrabKeysym code.") +Signed-off-by: Alan Coopersmith +Part-of: +--- + Xi/xipassivegrab.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c +index c9ac2f855..896233bec 100644 +--- a/Xi/xipassivegrab.c ++++ b/Xi/xipassivegrab.c +@@ -93,6 +93,7 @@ ProcXIPassiveGrabDevice(ClientPtr client) + GrabParameters param; + void *tmp; + int mask_len; ++ uint32_t length; + + REQUEST(xXIPassiveGrabDeviceReq); + REQUEST_FIXED_SIZE(xXIPassiveGrabDeviceReq, +@@ -247,9 +248,11 @@ ProcXIPassiveGrabDevice(ClientPtr client) + } + } + ++ /* save the value before SRepXIPassiveGrabDevice swaps it */ ++ length = rep.length; + WriteReplyToClient(client, sizeof(rep), &rep); + if (rep.num_modifiers) +- WriteToClient(client, rep.length * 4, modifiers_failed); ++ WriteToClient(client, length * 4, modifiers_failed); + + out: + free(modifiers_failed); +-- +2.44.0 + diff --git a/SOURCES/0002-dix-keep-a-ref-to-the-rootCursor.patch b/SOURCES/0002-dix-keep-a-ref-to-the-rootCursor.patch new file mode 100644 index 0000000..486c484 --- /dev/null +++ b/SOURCES/0002-dix-keep-a-ref-to-the-rootCursor.patch @@ -0,0 +1,49 @@ +From 9dc8beff846a127cc8754212fb654e5f66dacff4 Mon Sep 17 00:00:00 2001 +From: Peter Hutterer +Date: Wed, 4 Dec 2024 15:49:43 +1000 +Subject: [PATCH xserver 02/13] dix: keep a ref to the rootCursor + +CreateCursor returns a cursor with refcount 1 - that refcount is used by +the resource system, any caller needs to call RefCursor to get their own +reference. That happens correctly for normal cursors but for our +rootCursor we keep a variable to the cursor despite not having a ref for +ourselves. + +Fix this by reffing/unreffing the rootCursor to ensure our pointer is +valid. + +Related to CVE-2025-26594, ZDI-CAN-25544 + +Reviewed-by: Olivier Fourdan +(cherry picked from commit b0a09ba6020147961acc62d9c73d807b4cccd9f7) + +Part-of: +--- + dix/main.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/dix/main.c b/dix/main.c +index b228d9c28..f2606d3d6 100644 +--- a/dix/main.c ++++ b/dix/main.c +@@ -235,6 +235,8 @@ dix_main(int argc, char *argv[], char *envp[]) + defaultCursorFont); + } + ++ rootCursor = RefCursor(rootCursor); ++ + #ifdef PANORAMIX + /* + * Consolidate window and colourmap information for each screen +@@ -275,6 +277,8 @@ dix_main(int argc, char *argv[], char *envp[]) + + Dispatch(); + ++ UnrefCursor(rootCursor); ++ + UndisplayDevices(); + DisableAllDevices(); + +-- +2.48.1 + diff --git a/SOURCES/0002-os-Do-not-overflow-the-integer-size-with-BigRequest.patch b/SOURCES/0002-os-Do-not-overflow-the-integer-size-with-BigRequest.patch new file mode 100644 index 0000000..f72b33b --- /dev/null +++ b/SOURCES/0002-os-Do-not-overflow-the-integer-size-with-BigRequest.patch @@ -0,0 +1,91 @@ +From a99c927aec4563101f574d0a65cd451dcdd7e012 Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Mon, 7 Apr 2025 16:13:34 +0200 +Subject: [PATCH xserver 2/7] os: Do not overflow the integer size with + BigRequest +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The BigRequest extension allows requests larger than the 16-bit length +limit. + +It uses integers for the request length and checks for the size not to +exceed the maxBigRequestSize limit, but does so after translating the +length to integer by multiplying the given size in bytes by 4. + +In doing so, it might overflow the integer size limit before actually +checking for the overflow, defeating the purpose of the test. + +To avoid the issue, make sure to check that the request size does not +overflow the maxBigRequestSize limit prior to any conversion. + +The caller Dispatch() function however expects the return value to be in +bytes, so we cannot just return the converted value in case of error, as +that would also overflow the integer size. + +To preserve the existing API, we use a negative value for the X11 error +code BadLength as the function only return positive values, 0 or -1 and +update the caller Dispatch() function to take that case into account to +return the error code to the offending client. + +CVE-2025-49176 + +This issue was discovered by Nils Emmerich and +reported by Julian Suleder via ERNW Vulnerability Disclosure. + +Signed-off-by: Olivier Fourdan +Reviewed-by: Michel Dänzer +(cherry picked from commit 03731b326a80b582e48d939fe62cb1e2b10400d9) + +Part-of: +--- + dix/dispatch.c | 9 +++++---- + os/io.c | 4 ++++ + 2 files changed, 9 insertions(+), 4 deletions(-) + +diff --git a/dix/dispatch.c b/dix/dispatch.c +index a33bfaa9e..14ccdc57a 100644 +--- a/dix/dispatch.c ++++ b/dix/dispatch.c +@@ -447,9 +447,10 @@ Dispatch(void) + + /* now, finally, deal with client requests */ + result = ReadRequestFromClient(client); +- if (result <= 0) { +- if (result < 0) +- CloseDownClient(client); ++ if (result == 0) ++ break; ++ else if (result == -1) { ++ CloseDownClient(client); + break; + } + +@@ -470,7 +471,7 @@ Dispatch(void) + client->index, + client->requestBuffer); + #endif +- if (result > (maxBigRequestSize << 2)) ++ if (result < 0 || result > (maxBigRequestSize << 2)) + result = BadLength; + else { + result = XaceHookDispatch(client, client->majorOp); +diff --git a/os/io.c b/os/io.c +index 939f51743..a05300869 100644 +--- a/os/io.c ++++ b/os/io.c +@@ -296,6 +296,10 @@ ReadRequestFromClient(ClientPtr client) + needed = get_big_req_len(request, client); + } + client->req_len = needed; ++ if (needed > MAXINT >> 2) { ++ /* Check for potential integer overflow */ ++ return -(BadLength); ++ } + needed <<= 2; /* needed is in bytes now */ + } + if (gotnow < needed) { +-- +2.49.0 + diff --git a/SOURCES/0003-Xquartz-ProcAppleDRICreatePixmap-needs-to-use-unswap.patch b/SOURCES/0003-Xquartz-ProcAppleDRICreatePixmap-needs-to-use-unswap.patch new file mode 100644 index 0000000..df0a498 --- /dev/null +++ b/SOURCES/0003-Xquartz-ProcAppleDRICreatePixmap-needs-to-use-unswap.patch @@ -0,0 +1,47 @@ +From 6c684d035c06fd41c727f0ef0744517580864cef Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Fri, 22 Mar 2024 19:07:34 -0700 +Subject: [PATCH 3/4] Xquartz: ProcAppleDRICreatePixmap needs to use unswapped + length to send reply + +CVE-2024-31082 + +Fixes: 14205ade0 ("XQuartz: appledri: Fix byte swapping in replies") +Signed-off-by: Alan Coopersmith +Part-of: +--- + hw/xquartz/xpr/appledri.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/hw/xquartz/xpr/appledri.c b/hw/xquartz/xpr/appledri.c +index 77574655b..40422b61a 100644 +--- a/hw/xquartz/xpr/appledri.c ++++ b/hw/xquartz/xpr/appledri.c +@@ -272,6 +272,7 @@ ProcAppleDRICreatePixmap(ClientPtr client) + xAppleDRICreatePixmapReply rep; + int width, height, pitch, bpp; + void *ptr; ++ CARD32 stringLength; + + REQUEST_SIZE_MATCH(xAppleDRICreatePixmapReq); + +@@ -307,6 +308,7 @@ ProcAppleDRICreatePixmap(ClientPtr client) + if (sizeof(rep) != sz_xAppleDRICreatePixmapReply) + ErrorF("error sizeof(rep) is %zu\n", sizeof(rep)); + ++ stringLength = rep.stringLength; /* save unswapped value */ + if (client->swapped) { + swaps(&rep.sequenceNumber); + swapl(&rep.length); +@@ -319,7 +321,7 @@ ProcAppleDRICreatePixmap(ClientPtr client) + } + + WriteToClient(client, sizeof(rep), &rep); +- WriteToClient(client, rep.stringLength, path); ++ WriteToClient(client, stringLength, path); + + return Success; + } +-- +2.44.0 + diff --git a/SOURCES/0003-os-Check-for-integer-overflow-on-BigRequest-length.patch b/SOURCES/0003-os-Check-for-integer-overflow-on-BigRequest-length.patch new file mode 100644 index 0000000..1c70fff --- /dev/null +++ b/SOURCES/0003-os-Check-for-integer-overflow-on-BigRequest-length.patch @@ -0,0 +1,35 @@ +From d5b66f2b1f3d9a322261d150e0da4e707a337334 Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Wed, 18 Jun 2025 08:39:02 +0200 +Subject: [PATCH xserver 3/7] os: Check for integer overflow on BigRequest + length + +Check for another possible integer overflow once we get a complete xReq +with BigRequest. + +Related to CVE-2025-49176 + +Signed-off-by: Olivier Fourdan +Suggested-by: Peter Harris +Part-of: +(cherry picked from commit 4fc4d76b2c7aaed61ed2653f997783a3714c4fe1) +--- + os/io.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/os/io.c b/os/io.c +index a05300869..de5b3c921 100644 +--- a/os/io.c ++++ b/os/io.c +@@ -395,6 +395,8 @@ ReadRequestFromClient(ClientPtr client) + needed = get_big_req_len(request, client); + } + client->req_len = needed; ++ if (needed > MAXINT >> 2) ++ return -(BadLength); + needed <<= 2; + } + if (gotnow < needed) { +-- +2.49.0 + diff --git a/SOURCES/0003-xkb-Fix-buffer-overflow-in-XkbVModMaskText.patch b/SOURCES/0003-xkb-Fix-buffer-overflow-in-XkbVModMaskText.patch new file mode 100644 index 0000000..b805cfe --- /dev/null +++ b/SOURCES/0003-xkb-Fix-buffer-overflow-in-XkbVModMaskText.patch @@ -0,0 +1,63 @@ +From c0e295af1adca6a0258bb405c535fe04969cc178 Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Wed, 27 Nov 2024 14:41:45 +0100 +Subject: [PATCH xserver 03/13] xkb: Fix buffer overflow in XkbVModMaskText() + +The code in XkbVModMaskText() allocates a fixed sized buffer on the +stack and copies the virtual mod name. + +There's actually two issues in the code that can lead to a buffer +overflow. + +First, the bound check mixes pointers and integers using misplaced +parenthesis, defeating the bound check. + +But even though, if the check fails, the data is still copied, so the +stack overflow will occur regardless. + +Change the logic to skip the copy entirely if the bound check fails. + +CVE-2025-26595, ZDI-CAN-25545 + +This vulnerability was discovered by: +Jan-Niklas Sohn working with Trend Micro Zero Day Initiative + +Signed-off-by: Olivier Fourdan +Reviewed-by: Peter Hutterer +(cherry picked from commit 11fcda8753e994e15eb915d28cf487660ec8e722) + +Part-of: +--- + xkb/xkbtext.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/xkb/xkbtext.c b/xkb/xkbtext.c +index d2a2567fc..002626450 100644 +--- a/xkb/xkbtext.c ++++ b/xkb/xkbtext.c +@@ -175,14 +175,14 @@ XkbVModMaskText(XkbDescPtr xkb, + len = strlen(tmp) + 1 + (str == buf ? 0 : 1); + if (format == XkbCFile) + len += 4; +- if ((str - (buf + len)) <= VMOD_BUFFER_SIZE) { +- if (str != buf) { +- if (format == XkbCFile) +- *str++ = '|'; +- else +- *str++ = '+'; +- len--; +- } ++ if ((str - buf) + len > VMOD_BUFFER_SIZE) ++ continue; /* Skip */ ++ if (str != buf) { ++ if (format == XkbCFile) ++ *str++ = '|'; ++ else ++ *str++ = '+'; ++ len--; + } + if (format == XkbCFile) + sprintf(str, "%sMask", tmp); +-- +2.48.1 + diff --git a/SOURCES/0004-os-Account-for-bytes-to-ignore-when-sharing-input-bu.patch b/SOURCES/0004-os-Account-for-bytes-to-ignore-when-sharing-input-bu.patch new file mode 100644 index 0000000..2a43cfc --- /dev/null +++ b/SOURCES/0004-os-Account-for-bytes-to-ignore-when-sharing-input-bu.patch @@ -0,0 +1,48 @@ +From b4f63879f2a5cf0578101591f26471238f944e9c Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Mon, 28 Apr 2025 10:46:03 +0200 +Subject: [PATCH xserver 4/7] os: Account for bytes to ignore when sharing + input buffer + +When reading requests from the clients, the input buffer might be shared +and used between different clients. + +If a given client sends a full request with non-zero bytes to ignore, +the bytes to ignore may still be non-zero even though the request is +full, in which case the buffer could be shared with another client who's +request will not be processed because of those bytes to ignore, leading +to a possible hang of the other client request. + +To avoid the issue, make sure we have zero bytes to ignore left in the +input request when sharing the input buffer with another client. + +CVE-2025-49178 + +This issue was discovered by Nils Emmerich and +reported by Julian Suleder via ERNW Vulnerability Disclosure. + +Signed-off-by: Olivier Fourdan +Reviewed-by: Peter Hutterer +(cherry picked from commit d55c54cecb5e83eaa2d56bed5cc4461f9ba318c2) + +Part-of: +--- + os/io.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/os/io.c b/os/io.c +index de5b3c921..b7f2750b5 100644 +--- a/os/io.c ++++ b/os/io.c +@@ -444,7 +444,7 @@ ReadRequestFromClient(ClientPtr client) + */ + + gotnow -= needed; +- if (!gotnow) ++ if (!gotnow && !oci->ignoreBytes) + AvailableInput = oc; + if (move_header) { + if (client->req_len < bytes_to_int32(sizeof(xBigReq) - sizeof(xReq))) { +-- +2.49.0 + diff --git a/SOURCES/0004-render-fix-refcounting-of-glyphs-during-ProcRenderAd.patch b/SOURCES/0004-render-fix-refcounting-of-glyphs-during-ProcRenderAd.patch new file mode 100644 index 0000000..dcbf337 --- /dev/null +++ b/SOURCES/0004-render-fix-refcounting-of-glyphs-during-ProcRenderAd.patch @@ -0,0 +1,112 @@ +From bdca6c3d1f5057eeb31609b1280fc93237b00c77 Mon Sep 17 00:00:00 2001 +From: Peter Hutterer +Date: Tue, 30 Jan 2024 13:13:35 +1000 +Subject: [PATCH 4/4] render: fix refcounting of glyphs during + ProcRenderAddGlyphs + +Previously, AllocateGlyph would return a new glyph with refcount=0 and a +re-used glyph would end up not changing the refcount at all. The +resulting glyph_new array would thus have multiple entries pointing to +the same non-refcounted glyphs. + +AddGlyph may free a glyph, resulting in a UAF when the same glyph +pointer is then later used. + +Fix this by returning a refcount of 1 for a new glyph and always +incrementing the refcount for a re-used glyph, followed by dropping that +refcount back down again when we're done with it. + +CVE-2024-31083, ZDI-CAN-22880 + +This vulnerability was discovered by: +Jan-Niklas Sohn working with Trend Micro Zero Day Initiative + +Part-of: +--- + render/glyph.c | 5 +++-- + render/glyphstr_priv.h | 1 + + render/render.c | 15 +++++++++++---- + 3 files changed, 15 insertions(+), 6 deletions(-) + +diff --git a/render/glyph.c b/render/glyph.c +index 850ea8440..13991f8a1 100644 +--- a/render/glyph.c ++++ b/render/glyph.c +@@ -245,10 +245,11 @@ FreeGlyphPicture(GlyphPtr glyph) + } + } + +-static void ++void + FreeGlyph(GlyphPtr glyph, int format) + { + CheckDuplicates(&globalGlyphs[format], "FreeGlyph"); ++ BUG_RETURN(glyph->refcnt == 0); + if (--glyph->refcnt == 0) { + GlyphRefPtr gr; + int i; +@@ -354,7 +355,7 @@ AllocateGlyph(xGlyphInfo * gi, int fdepth) + glyph = (GlyphPtr) malloc(size); + if (!glyph) + return 0; +- glyph->refcnt = 0; ++ glyph->refcnt = 1; + glyph->size = size + sizeof(xGlyphInfo); + glyph->info = *gi; + dixInitPrivates(glyph, (char *) glyph + head_size, PRIVATE_GLYPH); +diff --git a/render/glyphstr.h b/render/glyphstr.h +index 2f51bd244..3b1d806d1 100644 +--- a/render/glyphstr.h ++++ b/render/glyphstr.h +@@ -108,6 +108,7 @@ extern Bool + extern GlyphPtr FindGlyph(GlyphSetPtr glyphSet, Glyph id); + + extern GlyphPtr AllocateGlyph(xGlyphInfo * gi, int format); ++extern void FreeGlyph(GlyphPtr glyph, int format); + + extern Bool + ResizeGlyphSet(GlyphSetPtr glyphSet, CARD32 change); +diff --git a/render/render.c b/render/render.c +index 29c5055c6..fe5e37dd9 100644 +--- a/render/render.c ++++ b/render/render.c +@@ -1076,6 +1076,7 @@ ProcRenderAddGlyphs(ClientPtr client) + + if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph) { + glyph_new->found = TRUE; ++ ++glyph_new->glyph->refcnt; + } + else { + GlyphPtr glyph; +@@ -1168,8 +1169,10 @@ ProcRenderAddGlyphs(ClientPtr client) + err = BadAlloc; + goto bail; + } +- for (i = 0; i < nglyphs; i++) ++ for (i = 0; i < nglyphs; i++) { + AddGlyph(glyphSet, glyphs[i].glyph, glyphs[i].id); ++ FreeGlyph(glyphs[i].glyph, glyphSet->fdepth); ++ } + + if (glyphsBase != glyphsLocal) + free(glyphsBase); +@@ -1179,9 +1182,13 @@ ProcRenderAddGlyphs(ClientPtr client) + FreePicture((void *) pSrc, 0); + if (pSrcPix) + FreeScratchPixmapHeader(pSrcPix); +- for (i = 0; i < nglyphs; i++) +- if (glyphs[i].glyph && !glyphs[i].found) +- free(glyphs[i].glyph); ++ for (i = 0; i < nglyphs; i++) { ++ if (glyphs[i].glyph) { ++ --glyphs[i].glyph->refcnt; ++ if (!glyphs[i].found) ++ free(glyphs[i].glyph); ++ } ++ } + if (glyphsBase != glyphsLocal) + free(glyphsBase); + return err; +-- +2.44.0 + diff --git a/SOURCES/0004-xkb-Fix-computation-of-XkbSizeKeySyms.patch b/SOURCES/0004-xkb-Fix-computation-of-XkbSizeKeySyms.patch new file mode 100644 index 0000000..8dbfa6b --- /dev/null +++ b/SOURCES/0004-xkb-Fix-computation-of-XkbSizeKeySyms.patch @@ -0,0 +1,47 @@ +From ddf9500846982402250114803b28180036a54cac Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Thu, 28 Nov 2024 11:49:34 +0100 +Subject: [PATCH xserver 04/13] xkb: Fix computation of XkbSizeKeySyms + +The computation of the length in XkbSizeKeySyms() differs from what is +actually written in XkbWriteKeySyms(), leading to a heap overflow. + +Fix the calculation in XkbSizeKeySyms() to match what kbWriteKeySyms() +does. + +CVE-2025-26596, ZDI-CAN-25543 + +This vulnerability was discovered by: +Jan-Niklas Sohn working with Trend Micro Zero Day Initiative + +Signed-off-by: Olivier Fourdan +Reviewed-by: Peter Hutterer +(cherry picked from commit 80d69f01423fc065c950e1ff4e8ddf9f675df773) + +Part-of: +--- + xkb/xkb.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/xkb/xkb.c b/xkb/xkb.c +index 68c59df02..175a81bf7 100644 +--- a/xkb/xkb.c ++++ b/xkb/xkb.c +@@ -1093,10 +1093,10 @@ XkbSizeKeySyms(XkbDescPtr xkb, xkbGetMapReply * rep) + len = rep->nKeySyms * SIZEOF(xkbSymMapWireDesc); + symMap = &xkb->map->key_sym_map[rep->firstKeySym]; + for (i = nSyms = 0; i < rep->nKeySyms; i++, symMap++) { +- if (symMap->offset != 0) { +- nSymsThisKey = XkbNumGroups(symMap->group_info) * symMap->width; +- nSyms += nSymsThisKey; +- } ++ nSymsThisKey = XkbNumGroups(symMap->group_info) * symMap->width; ++ if (nSymsThisKey == 0) ++ continue; ++ nSyms += nSymsThisKey; + } + len += nSyms * 4; + rep->totalSyms = nSyms; +-- +2.48.1 + diff --git a/SOURCES/0005-record-Check-for-overflow-in-RecordSanityCheckRegist.patch b/SOURCES/0005-record-Check-for-overflow-in-RecordSanityCheckRegist.patch new file mode 100644 index 0000000..3fff69b --- /dev/null +++ b/SOURCES/0005-record-Check-for-overflow-in-RecordSanityCheckRegist.patch @@ -0,0 +1,64 @@ +From d943eaa6b8584e7ceebd73ee59bd84e99b09be5d Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Mon, 28 Apr 2025 11:47:15 +0200 +Subject: [PATCH xserver 5/7] record: Check for overflow in + RecordSanityCheckRegisterClients() + +The RecordSanityCheckRegisterClients() checks for the request length, +but does not check for integer overflow. + +A client might send a very large value for either the number of clients +or the number of protocol ranges that will cause an integer overflow in +the request length computation, defeating the check for request length. + +To avoid the issue, explicitly check the number of clients against the +limit of clients (which is much lower than an maximum integer value) and +the number of protocol ranges (multiplied by the record length) do not +exceed the maximum integer value. + +This way, we ensure that the final computation for the request length +will not overflow the maximum integer limit. + +CVE-2025-49179 + +This issue was discovered by Nils Emmerich and +reported by Julian Suleder via ERNW Vulnerability Disclosure. + +Signed-off-by: Olivier Fourdan +Reviewed-by: Peter Hutterer +(cherry picked from commit 2bde9ca49a8fd9a1e6697d5e7ef837870d66f5d4) + +Part-of: +--- + record/record.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/record/record.c b/record/record.c +index a8aec23bd..afaceb55c 100644 +--- a/record/record.c ++++ b/record/record.c +@@ -45,6 +45,7 @@ and Jim Haggerty of Metheus. + #include "inputstr.h" + #include "eventconvert.h" + #include "scrnintstr.h" ++#include "opaque.h" + + #include + #include +@@ -1298,6 +1299,13 @@ RecordSanityCheckRegisterClients(RecordContextPtr pContext, ClientPtr client, + int i; + XID recordingClient; + ++ /* LimitClients is 2048 at max, way less that MAXINT */ ++ if (stuff->nClients > LimitClients) ++ return BadValue; ++ ++ if (stuff->nRanges > (MAXINT - 4 * stuff->nClients) / SIZEOF(xRecordRange)) ++ return BadValue; ++ + if (((client->req_len << 2) - SIZEOF(xRecordRegisterClientsReq)) != + 4 * stuff->nClients + SIZEOF(xRecordRange) * stuff->nRanges) + return BadLength; +-- +2.49.0 + diff --git a/SOURCES/0005-xkb-Fix-buffer-overflow-in-XkbChangeTypesOfKey.patch b/SOURCES/0005-xkb-Fix-buffer-overflow-in-XkbChangeTypesOfKey.patch new file mode 100644 index 0000000..2b4943b --- /dev/null +++ b/SOURCES/0005-xkb-Fix-buffer-overflow-in-XkbChangeTypesOfKey.patch @@ -0,0 +1,45 @@ +From 33dfc78a0f67f4db5558c2374f5a73d262e43671 Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Thu, 28 Nov 2024 14:09:04 +0100 +Subject: [PATCH xserver 05/13] xkb: Fix buffer overflow in + XkbChangeTypesOfKey() + +If XkbChangeTypesOfKey() is called with nGroups == 0, it will resize the +key syms to 0 but leave the key actions unchanged. + +If later, the same function is called with a non-zero value for nGroups, +this will cause a buffer overflow because the key actions are of the wrong +size. + +To avoid the issue, make sure to resize both the key syms and key actions +when nGroups is 0. + +CVE-2025-26597, ZDI-CAN-25683 + +This vulnerability was discovered by: +Jan-Niklas Sohn working with Trend Micro Zero Day Initiative + +Signed-off-by: Olivier Fourdan +Reviewed-by: Peter Hutterer +(cherry picked from commit 0e4ed94952b255c04fe910f6a1d9c852878dcd64) + +Part-of: +--- + xkb/XKBMisc.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/xkb/XKBMisc.c b/xkb/XKBMisc.c +index f17194528..c45471686 100644 +--- a/xkb/XKBMisc.c ++++ b/xkb/XKBMisc.c +@@ -553,6 +553,7 @@ XkbChangeTypesOfKey(XkbDescPtr xkb, + i = XkbSetNumGroups(i, 0); + xkb->map->key_sym_map[key].group_info = i; + XkbResizeKeySyms(xkb, key, 0); ++ XkbResizeKeyActions(xkb, key, 0); + return Success; + } + +-- +2.48.1 + diff --git a/SOURCES/0006-Xi-Fix-barrier-device-search.patch b/SOURCES/0006-Xi-Fix-barrier-device-search.patch new file mode 100644 index 0000000..0b46e2d --- /dev/null +++ b/SOURCES/0006-Xi-Fix-barrier-device-search.patch @@ -0,0 +1,118 @@ +From 475a856c919c8648aaefac9388a7788eed5725fa Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Mon, 16 Dec 2024 11:25:11 +0100 +Subject: [PATCH xserver 06/13] Xi: Fix barrier device search + +The function GetBarrierDevice() would search for the pointer device +based on its device id and return the matching value, or supposedly NULL +if no match was found. + +Unfortunately, as written, it would return the last element of the list +if no matching device id was found which can lead to out of bounds +memory access. + +Fix the search function to return NULL if not matching device is found, +and adjust the callers to handle the case where the device cannot be +found. + +CVE-2025-26598, ZDI-CAN-25740 + +This vulnerability was discovered by: +Jan-Niklas Sohn working with Trend Micro Zero Day Initiative + +Signed-off-by: Olivier Fourdan +Reviewed-by: Peter Hutterer +(cherry picked from commit bba9df1a9d57234c76c0b93f88dacb143d01bca2) + +Part-of: +--- + Xi/xibarriers.c | 27 +++++++++++++++++++++++---- + 1 file changed, 23 insertions(+), 4 deletions(-) + +diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c +index 1926762ad..cb336f22b 100644 +--- a/Xi/xibarriers.c ++++ b/Xi/xibarriers.c +@@ -129,14 +129,15 @@ static void FreePointerBarrierClient(struct PointerBarrierClient *c) + + static struct PointerBarrierDevice *GetBarrierDevice(struct PointerBarrierClient *c, int deviceid) + { +- struct PointerBarrierDevice *pbd = NULL; ++ struct PointerBarrierDevice *p, *pbd = NULL; + +- xorg_list_for_each_entry(pbd, &c->per_device, entry) { +- if (pbd->deviceid == deviceid) ++ xorg_list_for_each_entry(p, &c->per_device, entry) { ++ if (p->deviceid == deviceid) { ++ pbd = p; + break; ++ } + } + +- BUG_WARN(!pbd); + return pbd; + } + +@@ -337,6 +338,9 @@ barrier_find_nearest(BarrierScreenPtr cs, DeviceIntPtr dev, + double distance; + + pbd = GetBarrierDevice(c, dev->id); ++ if (!pbd) ++ continue; ++ + if (pbd->seen) + continue; + +@@ -445,6 +449,9 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen, + nearest = &c->barrier; + + pbd = GetBarrierDevice(c, master->id); ++ if (!pbd) ++ continue; ++ + new_sequence = !pbd->hit; + + pbd->seen = TRUE; +@@ -485,6 +492,9 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen, + int flags = 0; + + pbd = GetBarrierDevice(c, master->id); ++ if (!pbd) ++ continue; ++ + pbd->seen = FALSE; + if (!pbd->hit) + continue; +@@ -679,6 +689,9 @@ BarrierFreeBarrier(void *data, XID id) + continue; + + pbd = GetBarrierDevice(c, dev->id); ++ if (!pbd) ++ continue; ++ + if (!pbd->hit) + continue; + +@@ -738,6 +751,8 @@ static void remove_master_func(void *res, XID id, void *devid) + barrier = container_of(b, struct PointerBarrierClient, barrier); + + pbd = GetBarrierDevice(barrier, *deviceid); ++ if (!pbd) ++ return; + + if (pbd->hit) { + BarrierEvent ev = { +@@ -903,6 +918,10 @@ ProcXIBarrierReleasePointer(ClientPtr client) + barrier = container_of(b, struct PointerBarrierClient, barrier); + + pbd = GetBarrierDevice(barrier, dev->id); ++ if (!pbd) { ++ client->errorValue = dev->id; ++ return BadDevice; ++ } + + if (pbd->barrier_event_id == event_id) + pbd->release_event_id = event_id; +-- +2.48.1 + diff --git a/SOURCES/0006-randr-Check-for-overflow-in-RRChangeProviderProperty.patch b/SOURCES/0006-randr-Check-for-overflow-in-RRChangeProviderProperty.patch new file mode 100644 index 0000000..f748f9b --- /dev/null +++ b/SOURCES/0006-randr-Check-for-overflow-in-RRChangeProviderProperty.patch @@ -0,0 +1,43 @@ +From 3d44c08d94e850769d7d16fce0596536370253b1 Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Tue, 20 May 2025 15:18:19 +0200 +Subject: [PATCH xserver 6/7] randr: Check for overflow in + RRChangeProviderProperty() + +A client might send a request causing an integer overflow when computing +the total size to allocate in RRChangeProviderProperty(). + +To avoid the issue, check that total length in bytes won't exceed the +maximum integer value. + +CVE-2025-49180 + +This issue was discovered by Nils Emmerich and +reported by Julian Suleder via ERNW Vulnerability Disclosure. + +Signed-off-by: Olivier Fourdan +Reviewed-by: Peter Hutterer +(cherry picked from commit 3c3a4b767b16174d3213055947ea7f4f88e10ec6) + +Part-of: +--- + randr/rrproviderproperty.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/randr/rrproviderproperty.c b/randr/rrproviderproperty.c +index b79c17f9b..7088570ee 100644 +--- a/randr/rrproviderproperty.c ++++ b/randr/rrproviderproperty.c +@@ -179,7 +179,8 @@ RRChangeProviderProperty(RRProviderPtr provider, Atom property, Atom type, + + if (mode == PropModeReplace || len > 0) { + void *new_data = NULL, *old_data = NULL; +- ++ if (total_len > MAXINT / size_in_bytes) ++ return BadValue; + total_size = total_len * size_in_bytes; + new_value.data = (void *) malloc(total_size); + if (!new_value.data && total_size) { +-- +2.49.0 + diff --git a/SOURCES/0007-composite-Handle-failure-to-redirect-in-compRedirect.patch b/SOURCES/0007-composite-Handle-failure-to-redirect-in-compRedirect.patch new file mode 100644 index 0000000..2ec6900 --- /dev/null +++ b/SOURCES/0007-composite-Handle-failure-to-redirect-in-compRedirect.patch @@ -0,0 +1,65 @@ +From 04d8041534d40e975d11a8a58ea7e8b1f09b519d Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Tue, 17 Dec 2024 15:19:45 +0100 +Subject: [PATCH xserver 07/13] composite: Handle failure to redirect in + compRedirectWindow() + +The function compCheckRedirect() may fail if it cannot allocate the +backing pixmap. + +In that case, compRedirectWindow() will return a BadAlloc error. + +However that failure code path will shortcut the validation of the +window tree marked just before, which leaves the validate data partly +initialized. + +That causes a use of uninitialized pointer later. + +The fix is to not shortcut the call to compHandleMarkedWindows() even in +the case of compCheckRedirect() returning an error. + +CVE-2025-26599, ZDI-CAN-25851 + +This vulnerability was discovered by: +Jan-Niklas Sohn working with Trend Micro Zero Day Initiative + +Signed-off-by: Olivier Fourdan +Acked-by: Peter Hutterer +(cherry picked from commit c1ff84bef2569b4ba4be59323cf575d1798ba9be) + +Part-of: +--- + composite/compalloc.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/composite/compalloc.c b/composite/compalloc.c +index 3e2f14fb0..55a1b725a 100644 +--- a/composite/compalloc.c ++++ b/composite/compalloc.c +@@ -138,6 +138,7 @@ compRedirectWindow(ClientPtr pClient, WindowPtr pWin, int update) + CompScreenPtr cs = GetCompScreen(pWin->drawable.pScreen); + WindowPtr pLayerWin; + Bool anyMarked = FALSE; ++ int status = Success; + + if (pWin == cs->pOverlayWin) { + return Success; +@@ -216,13 +217,13 @@ compRedirectWindow(ClientPtr pClient, WindowPtr pWin, int update) + + if (!compCheckRedirect(pWin)) { + FreeResource(ccw->id, RT_NONE); +- return BadAlloc; ++ status = BadAlloc; + } + + if (anyMarked) + compHandleMarkedWindows(pWin, pLayerWin); + +- return Success; ++ return status; + } + + void +-- +2.48.1 + diff --git a/SOURCES/0007-xfree86-Check-for-RandR-provider-functions.patch b/SOURCES/0007-xfree86-Check-for-RandR-provider-functions.patch new file mode 100644 index 0000000..02cc596 --- /dev/null +++ b/SOURCES/0007-xfree86-Check-for-RandR-provider-functions.patch @@ -0,0 +1,50 @@ +From 8de5a9b2be31d14dcce3795f919b353d62e56897 Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Mon, 28 Apr 2025 14:59:46 +0200 +Subject: [PATCH xserver 7/7] xfree86: Check for RandR provider functions + +Changing XRandR provider properties if the driver has set no provider +function such as the modesetting driver will cause a NULL pointer +dereference and a crash of the Xorg server. + +Related to CVE-2025-49180 + +This issue was discovered by Nils Emmerich and +reported by Julian Suleder via ERNW Vulnerability Disclosure. + +Signed-off-by: Olivier Fourdan +Reviewed-by: Peter Hutterer +(cherry picked from commit 0235121c6a7a6eb247e2addb3b41ed6ef566853d) + +Part-of: +--- + hw/xfree86/modes/xf86RandR12.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c +index f220ef192..ccb7f629c 100644 +--- a/hw/xfree86/modes/xf86RandR12.c ++++ b/hw/xfree86/modes/xf86RandR12.c +@@ -2133,7 +2133,8 @@ xf86RandR14ProviderSetProperty(ScreenPtr pScreen, + /* If we don't have any property handler, then we don't care what the + * user is setting properties to. + */ +- if (config->provider_funcs->set_property == NULL) ++ if (config->provider_funcs == NULL || ++ config->provider_funcs->set_property == NULL) + return TRUE; + + /* +@@ -2151,7 +2152,8 @@ xf86RandR14ProviderGetProperty(ScreenPtr pScreen, + ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + +- if (config->provider_funcs->get_property == NULL) ++ if (config->provider_funcs == NULL || ++ config->provider_funcs->get_property == NULL) + return TRUE; + + /* Should be safe even w/o vtSema */ +-- +2.49.0 + diff --git a/SOURCES/0008-composite-initialize-border-clip-even-when-pixmap-al.patch b/SOURCES/0008-composite-initialize-border-clip-even-when-pixmap-al.patch new file mode 100644 index 0000000..cddb4ff --- /dev/null +++ b/SOURCES/0008-composite-initialize-border-clip-even-when-pixmap-al.patch @@ -0,0 +1,127 @@ +From 9a5a5b2972539ba5ef16dbc802c4eb87c9226d4e Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Mon, 13 Jan 2025 16:09:43 +0100 +Subject: [PATCH xserver 08/13] composite: initialize border clip even when + pixmap alloc fails + +If it fails to allocate the pixmap, the function compAllocPixmap() would +return early and leave the borderClip region uninitialized, which may +lead to the use of uninitialized value as reported by valgrind: + + Conditional jump or move depends on uninitialised value(s) + at 0x4F9B33: compClipNotify (compwindow.c:317) + by 0x484FC9: miComputeClips (mivaltree.c:476) + by 0x48559A: miValidateTree (mivaltree.c:679) + by 0x4F0685: MapWindow (window.c:2693) + by 0x4A344A: ProcMapWindow (dispatch.c:922) + by 0x4A25B5: Dispatch (dispatch.c:560) + by 0x4B082A: dix_main (main.c:282) + by 0x429233: main (stubmain.c:34) + Uninitialised value was created by a heap allocation + at 0x4841866: malloc (vg_replace_malloc.c:446) + by 0x4F47BC: compRedirectWindow (compalloc.c:171) + by 0x4FA8AD: compCreateWindow (compwindow.c:592) + by 0x4EBB89: CreateWindow (window.c:925) + by 0x4A2E6E: ProcCreateWindow (dispatch.c:768) + by 0x4A25B5: Dispatch (dispatch.c:560) + by 0x4B082A: dix_main (main.c:282) + by 0x429233: main (stubmain.c:34) + + Conditional jump or move depends on uninitialised value(s) + at 0x48EEDBC: pixman_region_translate (pixman-region.c:2233) + by 0x4F9255: RegionTranslate (regionstr.h:312) + by 0x4F9B7E: compClipNotify (compwindow.c:319) + by 0x484FC9: miComputeClips (mivaltree.c:476) + by 0x48559A: miValidateTree (mivaltree.c:679) + by 0x4F0685: MapWindow (window.c:2693) + by 0x4A344A: ProcMapWindow (dispatch.c:922) + by 0x4A25B5: Dispatch (dispatch.c:560) + by 0x4B082A: dix_main (main.c:282) + by 0x429233: main (stubmain.c:34) + Uninitialised value was created by a heap allocation + at 0x4841866: malloc (vg_replace_malloc.c:446) + by 0x4F47BC: compRedirectWindow (compalloc.c:171) + by 0x4FA8AD: compCreateWindow (compwindow.c:592) + by 0x4EBB89: CreateWindow (window.c:925) + by 0x4A2E6E: ProcCreateWindow (dispatch.c:768) + by 0x4A25B5: Dispatch (dispatch.c:560) + by 0x4B082A: dix_main (main.c:282) + by 0x429233: main (stubmain.c:34) + + Conditional jump or move depends on uninitialised value(s) + at 0x48EEE33: UnknownInlinedFun (pixman-region.c:2241) + by 0x48EEE33: pixman_region_translate (pixman-region.c:2225) + by 0x4F9255: RegionTranslate (regionstr.h:312) + by 0x4F9B7E: compClipNotify (compwindow.c:319) + by 0x484FC9: miComputeClips (mivaltree.c:476) + by 0x48559A: miValidateTree (mivaltree.c:679) + by 0x4F0685: MapWindow (window.c:2693) + by 0x4A344A: ProcMapWindow (dispatch.c:922) + by 0x4A25B5: Dispatch (dispatch.c:560) + by 0x4B082A: dix_main (main.c:282) + by 0x429233: main (stubmain.c:34) + Uninitialised value was created by a heap allocation + at 0x4841866: malloc (vg_replace_malloc.c:446) + by 0x4F47BC: compRedirectWindow (compalloc.c:171) + by 0x4FA8AD: compCreateWindow (compwindow.c:592) + by 0x4EBB89: CreateWindow (window.c:925) + by 0x4A2E6E: ProcCreateWindow (dispatch.c:768) + by 0x4A25B5: Dispatch (dispatch.c:560) + by 0x4B082A: dix_main (main.c:282) + by 0x429233: main (stubmain.c:34) + +Fix compAllocPixmap() to initialize the border clip even if the creation +of the backing pixmap has failed, to avoid depending later on +uninitialized border clip values. + +Related to CVE-2025-26599, ZDI-CAN-25851 + +Signed-off-by: Olivier Fourdan +Acked-by: Peter Hutterer +(cherry picked from commit b07192a8bedb90b039dc0f70ae69daf047ff9598) + +Part-of: +--- + composite/compalloc.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/composite/compalloc.c b/composite/compalloc.c +index 55a1b725a..d1c205ca0 100644 +--- a/composite/compalloc.c ++++ b/composite/compalloc.c +@@ -604,9 +604,12 @@ compAllocPixmap(WindowPtr pWin) + int h = pWin->drawable.height + (bw << 1); + PixmapPtr pPixmap = compNewPixmap(pWin, x, y, w, h); + CompWindowPtr cw = GetCompWindow(pWin); ++ Bool status; + +- if (!pPixmap) +- return FALSE; ++ if (!pPixmap) { ++ status = FALSE; ++ goto out; ++ } + if (cw->update == CompositeRedirectAutomatic) + pWin->redirectDraw = RedirectDrawAutomatic; + else +@@ -620,14 +623,16 @@ compAllocPixmap(WindowPtr pWin) + DamageRegister(&pWin->drawable, cw->damage); + cw->damageRegistered = TRUE; + } ++ status = TRUE; + ++out: + /* Make sure our borderClip is up to date */ + RegionUninit(&cw->borderClip); + RegionCopy(&cw->borderClip, &pWin->borderClip); + cw->borderClipX = pWin->drawable.x; + cw->borderClipY = pWin->drawable.y; + +- return TRUE; ++ return status; + } + + void +-- +2.48.1 + diff --git a/SOURCES/0009-dix-Dequeue-pending-events-on-frozen-device-on-remov.patch b/SOURCES/0009-dix-Dequeue-pending-events-on-frozen-device-on-remov.patch new file mode 100644 index 0000000..e6ca275 --- /dev/null +++ b/SOURCES/0009-dix-Dequeue-pending-events-on-frozen-device-on-remov.patch @@ -0,0 +1,67 @@ +From 470c77ae761a36c71494285009bc37b2abbefe97 Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Mon, 16 Dec 2024 16:18:04 +0100 +Subject: [PATCH xserver 09/13] dix: Dequeue pending events on frozen device on + removal + +When a device is removed while still frozen, the events queued for that +device remain while the device itself is freed. + +As a result, replaying the events will cause a use after free. + +To avoid the issue, make sure to dequeue and free any pending events on +a frozen device when removed. + +CVE-2025-26600, ZDI-CAN-25871 + +This vulnerability was discovered by: +Jan-Niklas Sohn working with Trend Micro Zero Day Initiative + +Signed-off-by: Olivier Fourdan +Reviewed-by: Peter Hutterer +(cherry picked from commit 6e0f332ba4c8b8c9a9945dc9d7989bfe06f80e14) + +Part-of: +--- + dix/devices.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/dix/devices.c b/dix/devices.c +index e7c74d7b7..11120b70b 100644 +--- a/dix/devices.c ++++ b/dix/devices.c +@@ -949,6 +949,23 @@ FreeAllDeviceClasses(ClassesPtr classes) + + } + ++static void ++FreePendingFrozenDeviceEvents(DeviceIntPtr dev) ++{ ++ QdEventPtr qe, tmp; ++ ++ if (!dev->deviceGrab.sync.frozen) ++ return; ++ ++ /* Dequeue any frozen pending events */ ++ xorg_list_for_each_entry_safe(qe, tmp, &syncEvents.pending, next) { ++ if (qe->device == dev) { ++ xorg_list_del(&qe->next); ++ free(qe); ++ } ++ } ++} ++ + /** + * Close down a device and free all resources. + * Once closed down, the driver will probably not expect you that you'll ever +@@ -1013,6 +1030,7 @@ CloseDevice(DeviceIntPtr dev) + free(dev->last.touches[j].valuators); + free(dev->last.touches); + dev->config_info = NULL; ++ FreePendingFrozenDeviceEvents(dev); + dixFreePrivates(dev->devPrivates, PRIVATE_DEVICE); + free(dev); + } +-- +2.48.1 + diff --git a/SOURCES/0010-sync-Do-not-let-sync-objects-uninitialized.patch b/SOURCES/0010-sync-Do-not-let-sync-objects-uninitialized.patch new file mode 100644 index 0000000..652f640 --- /dev/null +++ b/SOURCES/0010-sync-Do-not-let-sync-objects-uninitialized.patch @@ -0,0 +1,69 @@ +From 7f7f51e8907b14c6654944e0e321f15e256b34e7 Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Mon, 20 Jan 2025 16:52:01 +0100 +Subject: [PATCH xserver 10/13] sync: Do not let sync objects uninitialized + +When changing an alarm, the change mask values are evaluated one after +the other, changing the trigger values as requested and eventually, +SyncInitTrigger() is called. + +SyncInitTrigger() will evaluate the XSyncCACounter first and may free +the existing sync object. + +Other changes are then evaluated and may trigger an error and an early +return, not adding the new sync object. + +This can be used to cause a use after free when the alarm eventually +triggers. + +To avoid the issue, delete the existing sync object as late as possible +only once we are sure that no further error will cause an early exit. + +CVE-2025-26601, ZDI-CAN-25870 + +This vulnerability was discovered by: +Jan-Niklas Sohn working with Trend Micro Zero Day Initiative + +Signed-off-by: Olivier Fourdan +Reviewed-by: Peter Hutterer +(cherry picked from commit 16a1242d0ffc7f45ed3c595ee7564b5c04287e0b) + +Part-of: +--- + Xext/sync.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/Xext/sync.c b/Xext/sync.c +index fd2ceb042..e55295904 100644 +--- a/Xext/sync.c ++++ b/Xext/sync.c +@@ -329,11 +329,6 @@ SyncInitTrigger(ClientPtr client, SyncTrigger * pTrigger, XID syncObject, + client->errorValue = syncObject; + return rc; + } +- if (pSync != pTrigger->pSync) { /* new counter for trigger */ +- SyncDeleteTriggerFromSyncObject(pTrigger); +- pTrigger->pSync = pSync; +- newSyncObject = TRUE; +- } + } + + /* if system counter, ask it what the current value is */ +@@ -401,6 +396,14 @@ SyncInitTrigger(ClientPtr client, SyncTrigger * pTrigger, XID syncObject, + } + } + ++ if (changes & XSyncCACounter) { ++ if (pSync != pTrigger->pSync) { /* new counter for trigger */ ++ SyncDeleteTriggerFromSyncObject(pTrigger); ++ pTrigger->pSync = pSync; ++ newSyncObject = TRUE; ++ } ++ } ++ + /* we wait until we're sure there are no errors before registering + * a new counter on a trigger + */ +-- +2.48.1 + diff --git a/SOURCES/0011-sync-Check-values-before-applying-changes.patch b/SOURCES/0011-sync-Check-values-before-applying-changes.patch new file mode 100644 index 0000000..45b1ada --- /dev/null +++ b/SOURCES/0011-sync-Check-values-before-applying-changes.patch @@ -0,0 +1,83 @@ +From a4c19259fca5af558fb27d8fa98f2ad4a3689d56 Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Mon, 20 Jan 2025 16:54:30 +0100 +Subject: [PATCH xserver 11/13] sync: Check values before applying changes + +In SyncInitTrigger(), we would set the CheckTrigger function before +validating the counter value. + +As a result, if the counter value overflowed, we would leave the +function SyncInitTrigger() with the CheckTrigger applied but without +updating the trigger object. + +To avoid that issue, move the portion of code checking for the trigger +check value before updating the CheckTrigger function. + +Related to CVE-2025-26601, ZDI-CAN-25870 + +Signed-off-by: Olivier Fourdan +Reviewed-by: Peter Hutterer +(cherry picked from commit f52cea2f93a0c891494eb3334894442a92368030) + +Part-of: +--- + Xext/sync.c | 36 ++++++++++++++++++------------------ + 1 file changed, 18 insertions(+), 18 deletions(-) + +diff --git a/Xext/sync.c b/Xext/sync.c +index e55295904..66a52283d 100644 +--- a/Xext/sync.c ++++ b/Xext/sync.c +@@ -350,6 +350,24 @@ SyncInitTrigger(ClientPtr client, SyncTrigger * pTrigger, XID syncObject, + } + } + ++ if (changes & (XSyncCAValueType | XSyncCAValue)) { ++ if (pTrigger->value_type == XSyncAbsolute) ++ pTrigger->test_value = pTrigger->wait_value; ++ else { /* relative */ ++ Bool overflow; ++ ++ if (pCounter == NULL) ++ return BadMatch; ++ ++ overflow = checked_int64_add(&pTrigger->test_value, ++ pCounter->value, pTrigger->wait_value); ++ if (overflow) { ++ client->errorValue = pTrigger->wait_value >> 32; ++ return BadValue; ++ } ++ } ++ } ++ + if (changes & XSyncCATestType) { + + if (pSync && SYNC_FENCE == pSync->type) { +@@ -378,24 +396,6 @@ SyncInitTrigger(ClientPtr client, SyncTrigger * pTrigger, XID syncObject, + } + } + +- if (changes & (XSyncCAValueType | XSyncCAValue)) { +- if (pTrigger->value_type == XSyncAbsolute) +- pTrigger->test_value = pTrigger->wait_value; +- else { /* relative */ +- Bool overflow; +- +- if (pCounter == NULL) +- return BadMatch; +- +- overflow = checked_int64_add(&pTrigger->test_value, +- pCounter->value, pTrigger->wait_value); +- if (overflow) { +- client->errorValue = pTrigger->wait_value >> 32; +- return BadValue; +- } +- } +- } +- + if (changes & XSyncCACounter) { + if (pSync != pTrigger->pSync) { /* new counter for trigger */ + SyncDeleteTriggerFromSyncObject(pTrigger); +-- +2.48.1 + diff --git a/SOURCES/0012-sync-Do-not-fail-SyncAddTriggerToSyncObject.patch b/SOURCES/0012-sync-Do-not-fail-SyncAddTriggerToSyncObject.patch new file mode 100644 index 0000000..2d892d5 --- /dev/null +++ b/SOURCES/0012-sync-Do-not-fail-SyncAddTriggerToSyncObject.patch @@ -0,0 +1,50 @@ +From 7537745b5fe63d7e43d692bfa86f93259d522c80 Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Mon, 20 Jan 2025 17:06:07 +0100 +Subject: [PATCH xserver 12/13] sync: Do not fail SyncAddTriggerToSyncObject() + +We do not want to return a failure at the very last step in +SyncInitTrigger() after having all changes applied. + +SyncAddTriggerToSyncObject() must not fail on memory allocation, if the +allocation of the SyncTriggerList fails, trigger a FatalError() instead. + +Related to CVE-2025-26601, ZDI-CAN-25870 + +Signed-off-by: Olivier Fourdan +Reviewed-by: Peter Hutterer +(cherry picked from commit 8cbc90c8817306af75a60f494ec9dbb1061e50db) + +Part-of: +--- + Xext/sync.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/Xext/sync.c b/Xext/sync.c +index 66a52283d..8def4adbf 100644 +--- a/Xext/sync.c ++++ b/Xext/sync.c +@@ -199,8 +199,8 @@ SyncAddTriggerToSyncObject(SyncTrigger * pTrigger) + return Success; + } + +- if (!(pCur = malloc(sizeof(SyncTriggerList)))) +- return BadAlloc; ++ /* Failure is not an option, it's succeed or burst! */ ++ pCur = XNFalloc(sizeof(SyncTriggerList)); + + pCur->pTrigger = pTrigger; + pCur->next = pTrigger->pSync->pTriglist; +@@ -408,8 +408,7 @@ SyncInitTrigger(ClientPtr client, SyncTrigger * pTrigger, XID syncObject, + * a new counter on a trigger + */ + if (newSyncObject) { +- if ((rc = SyncAddTriggerToSyncObject(pTrigger)) != Success) +- return rc; ++ SyncAddTriggerToSyncObject(pTrigger); + } + else if (pCounter && IsSystemCounter(pCounter)) { + SyncComputeBracketValues(pCounter); +-- +2.48.1 + diff --git a/SOURCES/0013-sync-Apply-changes-last-in-SyncChangeAlarmAttributes.patch b/SOURCES/0013-sync-Apply-changes-last-in-SyncChangeAlarmAttributes.patch new file mode 100644 index 0000000..cdd2d77 --- /dev/null +++ b/SOURCES/0013-sync-Apply-changes-last-in-SyncChangeAlarmAttributes.patch @@ -0,0 +1,131 @@ +From e7bca6a0933b6f0c1568cbe770740c48626f30be Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +Date: Mon, 20 Jan 2025 17:10:31 +0100 +Subject: [PATCH xserver 13/13] sync: Apply changes last in + SyncChangeAlarmAttributes() + +SyncChangeAlarmAttributes() would apply the various changes while +checking for errors. + +If one of the changes triggers an error, the changes for the trigger, +counter or delta value would remain, possibly leading to inconsistent +changes. + +Postpone the actual changes until we're sure nothing else can go wrong. + +Related to CVE-2025-26601, ZDI-CAN-25870 + +Signed-off-by: Olivier Fourdan +Reviewed-by: Peter Hutterer +(cherry picked from commit c285798984c6bb99e454a33772cde23d394d3dcd) + +Part-of: +--- + Xext/sync.c | 42 +++++++++++++++++++++++++++--------------- + 1 file changed, 27 insertions(+), 15 deletions(-) + +diff --git a/Xext/sync.c b/Xext/sync.c +index 8def4adbf..e2f2c2774 100644 +--- a/Xext/sync.c ++++ b/Xext/sync.c +@@ -799,8 +799,14 @@ SyncChangeAlarmAttributes(ClientPtr client, SyncAlarm * pAlarm, Mask mask, + int status; + XSyncCounter counter; + Mask origmask = mask; ++ SyncTrigger trigger; ++ Bool select_events_changed = FALSE; ++ Bool select_events_value = FALSE; ++ int64_t delta; + +- counter = pAlarm->trigger.pSync ? pAlarm->trigger.pSync->id : None; ++ trigger = pAlarm->trigger; ++ delta = pAlarm->delta; ++ counter = trigger.pSync ? trigger.pSync->id : None; + + while (mask) { + int index2 = lowbit(mask); +@@ -816,24 +822,24 @@ SyncChangeAlarmAttributes(ClientPtr client, SyncAlarm * pAlarm, Mask mask, + case XSyncCAValueType: + mask &= ~XSyncCAValueType; + /* sanity check in SyncInitTrigger */ +- pAlarm->trigger.value_type = *values++; ++ trigger.value_type = *values++; + break; + + case XSyncCAValue: + mask &= ~XSyncCAValue; +- pAlarm->trigger.wait_value = ((int64_t)values[0] << 32) | values[1]; ++ trigger.wait_value = ((int64_t)values[0] << 32) | values[1]; + values += 2; + break; + + case XSyncCATestType: + mask &= ~XSyncCATestType; + /* sanity check in SyncInitTrigger */ +- pAlarm->trigger.test_type = *values++; ++ trigger.test_type = *values++; + break; + + case XSyncCADelta: + mask &= ~XSyncCADelta; +- pAlarm->delta = ((int64_t)values[0] << 32) | values[1]; ++ delta = ((int64_t)values[0] << 32) | values[1]; + values += 2; + break; + +@@ -843,10 +849,8 @@ SyncChangeAlarmAttributes(ClientPtr client, SyncAlarm * pAlarm, Mask mask, + client->errorValue = *values; + return BadValue; + } +- status = SyncEventSelectForAlarm(pAlarm, client, +- (Bool) (*values++)); +- if (status != Success) +- return status; ++ select_events_value = (Bool) (*values++); ++ select_events_changed = TRUE; + break; + + default: +@@ -855,25 +859,33 @@ SyncChangeAlarmAttributes(ClientPtr client, SyncAlarm * pAlarm, Mask mask, + } + } + ++ if (select_events_changed) { ++ status = SyncEventSelectForAlarm(pAlarm, client, select_events_value); ++ if (status != Success) ++ return status; ++ } ++ + /* "If the test-type is PositiveComparison or PositiveTransition + * and delta is less than zero, or if the test-type is + * NegativeComparison or NegativeTransition and delta is + * greater than zero, a Match error is generated." + */ + if (origmask & (XSyncCADelta | XSyncCATestType)) { +- if ((((pAlarm->trigger.test_type == XSyncPositiveComparison) || +- (pAlarm->trigger.test_type == XSyncPositiveTransition)) +- && pAlarm->delta < 0) ++ if ((((trigger.test_type == XSyncPositiveComparison) || ++ (trigger.test_type == XSyncPositiveTransition)) ++ && delta < 0) + || +- (((pAlarm->trigger.test_type == XSyncNegativeComparison) || +- (pAlarm->trigger.test_type == XSyncNegativeTransition)) +- && pAlarm->delta > 0) ++ (((trigger.test_type == XSyncNegativeComparison) || ++ (trigger.test_type == XSyncNegativeTransition)) ++ && delta > 0) + ) { + return BadMatch; + } + } + + /* postpone this until now, when we're sure nothing else can go wrong */ ++ pAlarm->delta = delta; ++ pAlarm->trigger = trigger; + if ((status = SyncInitTrigger(client, &pAlarm->trigger, counter, RTCounter, + origmask & XSyncCAAllTrigger)) != Success) + return status; +-- +2.48.1 + diff --git a/SPECS/xorg-x11-server.spec b/SPECS/xorg-x11-server.spec index 8f77499..b1146ae 100644 --- a/SPECS/xorg-x11-server.spec +++ b/SPECS/xorg-x11-server.spec @@ -42,7 +42,7 @@ Summary: X.Org X11 X server Name: xorg-x11-server Version: 1.20.11 -Release: 24%{?gitdate:.%{gitdate}}%{?dist} +Release: 31%{?gitdate:.%{gitdate}}%{?dist} URL: http://www.x.org License: MIT @@ -120,6 +120,12 @@ Patch112: 0001-present-Check-for-NULL-to-prevent-crash.patch # https://bugzilla.redhat.com/show_bug.cgi?id=2052605 Patch113: 0001-modesetting-Fix-msSharePixmapBacking-Segfault-Regres.patch Patch114: 0001-present-Send-a-PresentConfigureNotify-event-for-dest.patch +Patch115: 0001-xquartz-Remove-invalid-Unicode-sequence.patch +# https://issues.redhat.com/browse/RHEL-82085 +# https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1070 +Patch116: 0001-dix-Force-update-LEDs-after-device-state-update-in-E.patch +# https://issues.redhat.com/browse/RHEL-84253 +Patch117: 0001-xfree86-Fix-potentially-NULL-reference-to-platform-d.patch # CVE-2021-4011 Patch10009: 0001-record-Fix-out-of-bounds-access-in-SwapCreateRegiste.patch @@ -184,6 +190,54 @@ Patch10040: 0009-ephyr-xwayland-Use-the-proper-private-key-for-cursor.patch Patch10041: 0001-hw-Rename-boolean-config-value-field-from-bool-to-bo.patch # Related to CVE-2024-21886 Patch10042: 0001-dix-Fix-use-after-free-in-input-device-shutdown.patch +# Fix compilation error on i686 +Patch10043: 0001-ephyr-Fix-incompatible-pointer-type-build-error.patch +# Fix copy and paste error in CVE-2024-0229 +Patch10044: 0001-dix-fix-valuator-copy-paste-error-in-the-DeviceState.patch +# CVE-2024-31080 +Patch10045: 0001-Xi-ProcXIGetSelectedEvents-needs-to-use-unswapped-le.patch +# CVE-2024-31081 +Patch10046: 0002-Xi-ProcXIPassiveGrabDevice-needs-to-use-unswapped-le.patch +# CVE-2024-31082 +Patch10047: 0003-Xquartz-ProcAppleDRICreatePixmap-needs-to-use-unswap.patch +# CVE-2024-31083 +Patch10048: 0004-render-fix-refcounting-of-glyphs-during-ProcRenderAd.patch +Patch10049: 0001-render-Avoid-possible-double-free-in-ProcRenderAddGl.patch +# CVE-2024-9632 +Patch10050: 0001-xkb-Fix-buffer-overflow-in-_XkbSetCompatMap.patch +# CVE-2025-26594: Use-after-free of the root cursor +Patch10051: 0001-Cursor-Refuse-to-free-the-root-cursor.patch +Patch10052: 0002-dix-keep-a-ref-to-the-rootCursor.patch +# CVE-2025-26595: Buffer overflow in XkbVModMaskText() +Patch10053: 0003-xkb-Fix-buffer-overflow-in-XkbVModMaskText.patch +# CVE-2025-26596: Heap overflow in XkbWriteKeySyms() +Patch10054: 0004-xkb-Fix-computation-of-XkbSizeKeySyms.patch +# CVE-2025-26597: Buffer overflow in XkbChangeTypesOfKey() +Patch10055: 0005-xkb-Fix-buffer-overflow-in-XkbChangeTypesOfKey.patch +# CVE-2025-26598: Out-of-bounds write in CreatePointerBarrierClient() +Patch10056: 0006-Xi-Fix-barrier-device-search.patch +# CVE-2025-26599: Use of uninitialized pointer in compRedirectWindow() +Patch10057: 0007-composite-Handle-failure-to-redirect-in-compRedirect.patch +Patch10058: 0008-composite-initialize-border-clip-even-when-pixmap-al.patch +# CVE-2025-26600: Use-after-free in PlayReleasedEvents() +Patch10059: 0009-dix-Dequeue-pending-events-on-frozen-device-on-remov.patch +# CVE-2025-26601: Use-after-free in SyncInitTrigger() +Patch10060: 0010-sync-Do-not-let-sync-objects-uninitialized.patch +Patch10061: 0011-sync-Check-values-before-applying-changes.patch +Patch10062: 0012-sync-Do-not-fail-SyncAddTriggerToSyncObject.patch +Patch10063: 0013-sync-Apply-changes-last-in-SyncChangeAlarmAttributes.patch +# CVE-2025-49175: Out-of-bounds access in X Rendering extension +Patch10064: 0001-render-Avoid-0-or-less-animated-cursors.patch +# CVE-2025-49176: Integer overflow in Big Requests Extension +Patch10065: 0002-os-Do-not-overflow-the-integer-size-with-BigRequest.patch +Patch10066: 0003-os-Check-for-integer-overflow-on-BigRequest-length.patch +# CVE-2025-49178: Unprocessed client request via bytes to ignore +Patch10067: 0004-os-Account-for-bytes-to-ignore-when-sharing-input-bu.patch +# CVE-2025-49179: Integer overflow in X Record extension +Patch10068: 0005-record-Check-for-overflow-in-RecordSanityCheckRegist.patch +# CVE-2025-49180: Integer overflow in RandR extension +Patch10069: 0006-randr-Check-for-overflow-in-RRChangeProviderProperty.patch +Patch10070: 0007-xfree86-Check-for-RandR-provider-functions.patch BuildRequires: make BuildRequires: systemtap-sdt-devel @@ -314,6 +368,7 @@ License: MIT and GPLv2 Requires: xorg-x11-server-common >= %{version}-%{release} # required for xvfb-run Requires: xorg-x11-xauth +Requires: util-linux Provides: Xvfb %description Xvfb @@ -593,7 +648,39 @@ find %{inst_srcdir}/hw/xfree86 -name \*.c -delete %changelog -* Thu Jan 18 2024 José Expósito - 1.20.4-24 +* Wed Jun 18 2025 Olivier Fourdan - 1.20.11-31 +- CVE fix for: CVE-2025-49175 (RHEL-97285), CVE-2025-49176 (RHEL-97308), + CVE-2025-49178 (RHEL-97387), CVE-2025-49179 (RHEL-97409), + CVE-2025-49180 (RHEL-97253) + +* Tue Apr 22 2025 Michel Dänzer - 1.20.11-30 +- xfree86: Fix potentially NULL reference to platform device's PCI device + Resolves: https://issues.redhat.com/browse/RHEL-84253 + +* Fri Mar 21 2025 Olivier Fourdan - 1.20.11-29 +- Fix LEDs state after suspend/resume + Resolves: https://issues.redhat.com/browse/RHEL-82085 + +* Wed Feb 26 2025 Olivier Fourdan - 1.20.11-28 +- CVE fix for: CVE-2025-26594 (RHEL-80201), CVE-2025-26595 (RHEL-80186), + CVE-2025-26596 (RHEL-80188), CVE-2025-26597 (RHEL-80191), + CVE-2025-26598 (RHEL-80192), CVE-2025-26599 (RHEL-80199), + CVE-2025-26600 (RHEL-80198), CVE-2025-26601 (RHEL-80200) + +* Tue Oct 29 2024 José Expósito - 1.20.11-27 +- CVE fix for CVE-2024-9632 +- Backport fix for invalid Unicode sequence + +* Wed Apr 10 2024 José Expósito - 1.20.11-26 +- Fix regression caused by the fix for CVE-2024-31083 + +* Thu Apr 04 2024 José Expósito - 1.20.11-25 +- CVE fix for: CVE-2024-31080, CVE-2024-31081, CVE-2024-31082 and + CVE-2024-31083 +- Add util-linux as a dependency of Xvfb +- Fix compilation error on i686 + +* Thu Jan 18 2024 José Expósito - 1.20.11-24 - Fix use after free related to CVE-2024-21886 * Tue Jan 16 2024 José Expósito - 1.20.11-23