Incomplete fix for race condition in GetPairedDevice?
When I was searching for race conditions in dix/devices.c I came across this commit.
commit e693c9657f98c334e9921ca2f8ebf710497c0c6a Author: Arthur Williams <firstname.lastname@example.org> Date: Sun Oct 6 11:55:35 2019 -0700 dix: Check for NULL spriteInfo in GetPairedDevice There is a race when reseting the XServer that causes spriteInfo to be NULL in GetPairedDevice resulting a segfault and subsequent crash. The problem was noticed when opening a connection, creating master devices, destroying master devices and closing the connection during testing. Signed-off-by: Arthur Williams <email@example.com> diff --git a/dix/devices.c b/dix/devices.c index 1b18b168e..00c453980 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -2656,7 +2656,7 @@ GetPairedDevice(DeviceIntPtr dev) if (!IsMaster(dev) && !IsFloating(dev)) dev = GetMaster(dev, MASTER_ATTACHED); - return dev->spriteInfo->paired; + return dev->spriteInfo? dev->spriteInfo->paired: NULL; } /**
The commit tries to fix a race condition but I'm not sure the fix is correct.
spriteInfo is modified in a different thread and can presumably become null at any point. The code tries to make sure spriteInfo is not null before dereferencing but the check and access are not atomic. spriteInfo could become null after the check but before the dereferencing. The commit reduced the timing window of the race but it can still crash.