From 01642f263f12becf803b19be4db95a4a83f94acc Mon Sep 17 00:00:00 2001 From: Olivier Fourdan Date: Wed, 27 Nov 2024 11:27:05 +0100 Subject: [PATCH] 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 Part-of: --- dix/dispatch.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dix/dispatch.c b/dix/dispatch.c index efb17c7346..b3e5feacc2 100644 --- a/dix/dispatch.c +++ b/dix/dispatch.c @@ -3123,6 +3123,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; } -- GitLab 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