summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2024-01-05 09:40:27 +1000
committerJosé Expósito <jose.exposito89@gmail.com>2024-01-16 09:58:06 +0100
commit5c4816afa7722ea47d1a7dea983a953e7b454d26 (patch)
tree4e246deb8c4470e66a841d75f35e7a0c30dcf420
parent7b5694368b3f3b039fb523e66b816c1323f3cc39 (diff)
dix: when disabling a master, float disabled slaved devices too
Disabling a master device floats all slave devices but we didn't do this to already-disabled slave devices. As a result those devices kept their reference to the master device resulting in access to already freed memory if the master device was removed before the corresponding slave device. And to match this behavior, also forcibly reset that pointer during CloseDownDevices(). Related to CVE-2024-21886, ZDI-CAN-22840 (cherry picked from commit 26769aa71fcbe0a8403b7fb13b7c9010cc07c3a8)
-rw-r--r--dix/devices.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/dix/devices.c b/dix/devices.c
index c3f30e6ee..1516147a5 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -477,6 +477,13 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
flags[other->id] |= XISlaveDetached;
}
}
+
+ for (other = inputInfo.off_devices; other; other = other->next) {
+ if (!IsMaster(other) && GetMaster(other, MASTER_ATTACHED) == dev) {
+ AttachDevice(NULL, other, NULL);
+ flags[other->id] |= XISlaveDetached;
+ }
+ }
}
else {
for (other = inputInfo.devices; other; other = other->next) {
@@ -1073,6 +1080,11 @@ CloseDownDevices(void)
dev->master = NULL;
}
+ for (dev = inputInfo.off_devices; dev; dev = dev->next) {
+ if (!IsMaster(dev) && !IsFloating(dev))
+ dev->master = NULL;
+ }
+
CloseDeviceList(&inputInfo.devices);
CloseDeviceList(&inputInfo.off_devices);