From 01642f263f12becf803b19be4db95a4a83f94acc Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Wed, 27 Nov 2024 11:27:05 +0100
Subject: [PATCH] Cursor: Refuse to free the root cursor

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
<peter.hutterer@who-t.net>)
v3: Return BadCursor instead of BadValue (Michel Danzer
<michel@daenzer.net>)

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Suggested-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1828>

Upstream-Status: Backport [https://gitlab.freedesktop.org/xorg/xserver/-/commit/01642f26]
CVE: CVE-2025-26594
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
---
 dix/dispatch.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/dix/dispatch.c b/dix/dispatch.c
index 4602961..30b95c1 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -3107,6 +3107,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.25.1

