Input: reduce raciness when input handlers disconnect
There is a race between input handler's release() and disconnect() methods: when input handler disconnects it wakes up all regular users and then process to walk user list to wake up async. users. While disconnect() walks the list release() removes elements of the same list causing oopses. While this is not a substibute for proper locking we can reduce odds of getting an oops if we wake up normal readers after walking the list. Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
This commit is contained in:
parent
26be5a509a
commit
1dfa281240
|
@ -700,9 +700,9 @@ static void evdev_disconnect(struct input_handle *handle)
|
|||
if (evdev->open) {
|
||||
input_flush_device(handle, NULL);
|
||||
input_close_device(handle);
|
||||
wake_up_interruptible(&evdev->wait);
|
||||
list_for_each_entry(client, &evdev->client_list, node)
|
||||
kill_fasync(&client->fasync, SIGIO, POLL_HUP);
|
||||
wake_up_interruptible(&evdev->wait);
|
||||
} else
|
||||
evdev_free(evdev);
|
||||
}
|
||||
|
|
|
@ -595,9 +595,9 @@ static void joydev_disconnect(struct input_handle *handle)
|
|||
|
||||
if (joydev->open) {
|
||||
input_close_device(handle);
|
||||
wake_up_interruptible(&joydev->wait);
|
||||
list_for_each_entry(client, &joydev->client_list, node)
|
||||
kill_fasync(&client->fasync, SIGIO, POLL_HUP);
|
||||
wake_up_interruptible(&joydev->wait);
|
||||
} else
|
||||
joydev_free(joydev);
|
||||
}
|
||||
|
|
|
@ -767,9 +767,9 @@ static void mousedev_disconnect(struct input_handle *handle)
|
|||
|
||||
if (mousedev->open) {
|
||||
input_close_device(handle);
|
||||
wake_up_interruptible(&mousedev->wait);
|
||||
list_for_each_entry(client, &mousedev->client_list, node)
|
||||
kill_fasync(&client->fasync, SIGIO, POLL_HUP);
|
||||
wake_up_interruptible(&mousedev->wait);
|
||||
} else
|
||||
mousedev_free(mousedev);
|
||||
}
|
||||
|
|
|
@ -477,9 +477,9 @@ static void tsdev_disconnect(struct input_handle *handle)
|
|||
|
||||
if (tsdev->open) {
|
||||
input_close_device(handle);
|
||||
wake_up_interruptible(&tsdev->wait);
|
||||
list_for_each_entry(client, &tsdev->client_list, node)
|
||||
kill_fasync(&client->fasync, SIGIO, POLL_HUP);
|
||||
wake_up_interruptible(&tsdev->wait);
|
||||
} else
|
||||
tsdev_free(tsdev);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue