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>
(cherry picked from commit f52cea2f93)

Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1831>
This commit is contained in:
Olivier Fourdan 2025-01-20 16:54:30 +01:00
parent 1932abe3d0
commit fb6df2a68c

View file

@ -351,6 +351,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) {
@ -379,24 +397,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);