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>
This commit is contained in:
		
							parent
							
								
									16a1242d0f
								
							
						
					
					
						commit
						f52cea2f93
					
				
							
								
								
									
										36
									
								
								Xext/sync.c
								
								
								
								
							
							
						
						
									
										36
									
								
								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); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue