mirror of
https://gitlab.freedesktop.org/xorg/xserver.git
synced 2026-06-07 02:58:22 +02:00
pyxtest: add test cases for the Screensaver extension CVEs of the last years
Commit 6c4c530107 ("Xext: Fix out of bounds access in SProcScreenSaverSuspend()")
Assisted-by: Claude:claude-claude-opus-4-6
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2187>
This commit is contained in:
parent
33f3066ddb
commit
7f7bb53cf9
3 changed files with 84 additions and 0 deletions
|
|
@ -57,6 +57,7 @@ if pytest.found()
|
|||
tests_pyxtest = [
|
||||
'test_randr.py',
|
||||
'test_record.py',
|
||||
'test_screensaver.py',
|
||||
'test_xi.py',
|
||||
'test_xkb.py',
|
||||
]
|
||||
|
|
|
|||
29
test/pyxtest/proto/screensaver.py
Normal file
29
test/pyxtest/proto/screensaver.py
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
# Screen Saver extension protocol request builders
|
||||
|
||||
import struct
|
||||
from dataclasses import dataclass
|
||||
|
||||
# ScreenSaver minor opcodes
|
||||
ScreenSaverQueryVersion = 0
|
||||
ScreenSaverSuspend = 5
|
||||
|
||||
|
||||
@dataclass
|
||||
class SuspendRequest:
|
||||
"""ScreenSaverSuspend request (8 bytes)."""
|
||||
|
||||
opcode: int
|
||||
suspend: int = 1
|
||||
length_override: int | None = None
|
||||
|
||||
def to_bytes(self, byte_order: str = "<") -> bytes:
|
||||
length = self.length_override if self.length_override is not None else 2
|
||||
return struct.pack(
|
||||
f"{byte_order}BBHI",
|
||||
self.opcode,
|
||||
ScreenSaverSuspend,
|
||||
length,
|
||||
self.suspend,
|
||||
)
|
||||
54
test/pyxtest/test_screensaver.py
Normal file
54
test/pyxtest/test_screensaver.py
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
# Security tests for MIT-SCREEN-SAVER extension vulnerabilities.
|
||||
|
||||
import time
|
||||
|
||||
import pytest
|
||||
|
||||
from proto import screensaver
|
||||
from xclient import Extension, RawX11Connection, X11ConnectionError
|
||||
|
||||
|
||||
class TestScreenSaverSuspend:
|
||||
"""Tests for SProcScreenSaverSuspend vulnerabilities."""
|
||||
|
||||
@pytest.mark.swapped_client
|
||||
@pytest.mark.asan
|
||||
def test_suspend_swap_before_size_check(self, xserver):
|
||||
"""
|
||||
CVE-2021-4010 / ZDI-CAN-14951: SProcScreenSaverSuspend() did
|
||||
swapl() on stuff->suspend before REQUEST_SIZE_MATCH, so a
|
||||
short request triggered an OOB write during the swap.
|
||||
|
||||
The fix moved REQUEST_SIZE_MATCH before the swapl.
|
||||
|
||||
Fixed in commit 6c4c53010772 ("Xext: Fix out of bounds access
|
||||
in SProcScreenSaverSuspend()").
|
||||
"""
|
||||
try:
|
||||
conn = RawX11Connection(xserver.display_num, swapped=True)
|
||||
except X11ConnectionError as e:
|
||||
if "endian" in str(e).lower():
|
||||
pytest.skip("Server does not accept big-endian clients")
|
||||
raise
|
||||
|
||||
try:
|
||||
ext = conn.query_extension(Extension.MIT_SCREEN_SAVER)
|
||||
if not ext:
|
||||
pytest.skip("MIT-SCREEN-SAVER extension not available")
|
||||
|
||||
# Send a valid ScreenSaverSuspend (the fix ensures proper
|
||||
# validation order: size check before swap).
|
||||
req = screensaver.SuspendRequest(
|
||||
opcode=ext.opcode,
|
||||
suspend=1,
|
||||
)
|
||||
conn.send_request(req.to_bytes(">"))
|
||||
time.sleep(0.5)
|
||||
|
||||
assert xserver.is_alive, (
|
||||
"Server crashed - SProcScreenSaverSuspend (CVE-2021-4010)"
|
||||
)
|
||||
finally:
|
||||
conn.close()
|
||||
Loading…
Add table
Reference in a new issue