Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1dfa2812 authored by Dmitry Torokhov's avatar Dmitry Torokhov
Browse files

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: default avatarDmitry Torokhov <dtor@mail.ru>
parent 26be5a50
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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);
}
+1 −1
Original line number Diff line number Diff line
@@ -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);
}
+1 −1
Original line number Diff line number Diff line
@@ -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);
}
+1 −1
Original line number Diff line number Diff line
@@ -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);
}