Allow driver to call DeleteInputDeviceRequest during UnInit

When the input driver (like xf86-input-wacom) removes it's devices
during a call to UnInit, the CloseDownDevices() cannot handle it. The
"next" variable can become a pointer to freed memory.

The patch introduces order-independent device freeing mechanism by
remembering the already freed device ids. The devices can reorder any
time during freeing. No device will be double-freed - if the removing
failed for any reason; some implementations of DeleteInputDeviceRequest
don't free the devices already.

Signed-off-by: Oldřich Jedlička <oldium.pro@seznam.cz>
Reviewed-by: Simon Thum <simon.thum@gmx.de>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Oldřich Jedlička 2010-01-17 17:59:03 +01:00 committed by Peter Hutterer
parent b91cec26de
commit 08b22c7faf

View File

@ -876,6 +876,36 @@ CloseDevice(DeviceIntPtr dev)
xfree(dev); xfree(dev);
} }
/**
* Shut down all devices of one list and free all resources.
*/
static
void
CloseDeviceList(DeviceIntPtr *listHead)
{
/* Used to mark devices that we tried to free */
Bool freedIds[MAXDEVICES];
DeviceIntPtr dev;
int i;
if (listHead == NULL)
return;
for (i = 0; i < MAXDEVICES; i++)
freedIds[i] = FALSE;
dev = *listHead;
while (dev != NULL)
{
freedIds[dev->id] = TRUE;
DeleteInputDeviceRequest(dev);
dev = *listHead;
while (dev != NULL && freedIds[dev->id])
dev = dev->next;
}
}
/** /**
* Shut down all devices, free all resources, etc. * Shut down all devices, free all resources, etc.
* Only useful if you're shutting down the server! * Only useful if you're shutting down the server!
@ -883,7 +913,7 @@ CloseDevice(DeviceIntPtr dev)
void void
CloseDownDevices(void) CloseDownDevices(void)
{ {
DeviceIntPtr dev, next; DeviceIntPtr dev;
/* Float all SDs before closing them. Note that at this point resources /* Float all SDs before closing them. Note that at this point resources
* (e.g. cursors) have been freed already, so we can't just call * (e.g. cursors) have been freed already, so we can't just call
@ -896,16 +926,8 @@ CloseDownDevices(void)
dev->u.master = NULL; dev->u.master = NULL;
} }
for (dev = inputInfo.devices; dev; dev = next) CloseDeviceList(&inputInfo.devices);
{ CloseDeviceList(&inputInfo.off_devices);
next = dev->next;
DeleteInputDeviceRequest(dev);
}
for (dev = inputInfo.off_devices; dev; dev = next)
{
next = dev->next;
DeleteInputDeviceRequest(dev);
}
CloseDevice(inputInfo.pointer); CloseDevice(inputInfo.pointer);
CloseDevice(inputInfo.keyboard); CloseDevice(inputInfo.keyboard);