From f52cea2f93a0c891494eb3334894442a92368030 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Mon, 20 Jan 2025 16:54:30 +0100
Subject: [PATCH] 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 <ofourdan@redhat.com>
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/f52cea2f]
CVE: CVE-2025-26601
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
---
 Xext/sync.c | 36 ++++++++++++++++++------------------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/Xext/sync.c b/Xext/sync.c
index 585cfa6f68..10302160fb 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -381,6 +381,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) {
@@ -409,24 +427,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);
-- 
GitLab

