Commit d9c4f846 authored by Samu Onkalo's avatar Samu Onkalo Committed by Dmitry Torokhov

Input: polldev can cause crash in case when polling disabled

When polled input device is opened and closed and there are no other
users of polled device, the workqueue is created and destroyed in
every open / close operation. It is probable that at some point
dynamic allocation of internal parts of the workqueue cause changes to the
workqueue.

When a work is queued to the workqueue the work struct contains pointers
to the workqueue data. If the workqueue has been changed and the work
has never been queued to the new workqueue, work-struct contains pointers
to the non-existing workqueue. This will cause crash at the work
cancellation during device close since cancellation of a work assumes
that the workqueue exists.

To prevent that, work struct is cleaned up at device close. This keeps
work struct clean for the next use.
Signed-off-by: default avatarSamu Onkalo <samu.p.onkalo@nokia.com>
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent 3b77fd8e
...@@ -100,6 +100,12 @@ static void input_close_polled_device(struct input_dev *input) ...@@ -100,6 +100,12 @@ static void input_close_polled_device(struct input_dev *input)
struct input_polled_dev *dev = input_get_drvdata(input); struct input_polled_dev *dev = input_get_drvdata(input);
cancel_delayed_work_sync(&dev->work); cancel_delayed_work_sync(&dev->work);
/*
* Clean up work struct to remove references to the workqueue.
* It may be destroyed by the next call. This causes problems
* at next device open-close in case of poll_interval == 0.
*/
INIT_DELAYED_WORK(&dev->work, dev->work.work.func);
input_polldev_stop_workqueue(); input_polldev_stop_workqueue();
if (dev->close) if (dev->close)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment