[input] Remove closed device in correct place

Removing the device from the devices list after closing the device
could cause the device to be double-freed if something went wrong in the
device removal callback resulting in system shutdown which would then
close all open devices.

The device is removed from the list before the callback is called.

There's still a small opportunity for such in a multi-threaded
environment, but that would take device removal occurring at the same
time as the input system is shut down. Probably the responsibility of
the threaded environment rather than inputlib.
This commit is contained in:
Bill Currie 2021-09-25 16:37:38 +09:00
parent 13bc38a55b
commit 192b76ddc6
2 changed files with 11 additions and 6 deletions

View File

@ -18,6 +18,7 @@ typedef struct {
typedef struct device_s {
struct device_s *next;
struct device_s **prev;
char *path;
char *name;
char *phys;

View File

@ -199,6 +199,10 @@ check_device (const char *path)
dev = malloc (sizeof (device_t));
dev->next = devices;
dev->prev = &devices;
if (devices) {
devices->prev = &dev->next;
}
devices = dev;
dev->path = strdup (path);
@ -355,6 +359,11 @@ inputlib_check_input (void)
static void
close_device (device_t *dev)
{
if (dev->next) {
dev->next->prev = dev->prev;
}
*dev->prev = dev->next;
if (device_remove) {
device_remove (dev);
}
@ -370,6 +379,7 @@ close_device (device_t *dev)
}
free (dev->name);
free (dev->path);
free (dev);
}
static char *
@ -428,9 +438,6 @@ device_deleted (const char *name)
if (strcmp ((*dev)->path, devname) == 0) {
//Sys_Printf ("lost device %s\n", (*dev)->path);
close_device (*dev);
device_t *d = *dev;
*dev = (*dev)->next;
free (d);
break;
}
}
@ -482,8 +489,5 @@ inputlib_close (void)
inputlib_hotplug_close ();
while (devices) {
close_device (devices);
device_t *dev = devices;
devices = devices->next;
free (dev);
}
}