diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-05-02 03:13:36 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-05-02 03:23:14 -0400 |
commit | dba4258068f822b7dafc78c28fe9c99c551eca7e (patch) | |
tree | 0df5af1962e330399822c2d21f57a629f0b2d15c /drivers/input | |
parent | f31ad406693f114e57ad4651eb17deb68419c7cb (diff) |
Input: evdev - properly access RCU-protected 'grab' data
We should use rcu_dereference_protected() when checking if given client
is the one that grabbed the device. This fixes warnings produced by
sparse.
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/evdev.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 4b2e10d5d641..9226b4d9118f 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -180,7 +180,10 @@ static int evdev_grab(struct evdev *evdev, struct evdev_client *client) | |||
180 | 180 | ||
181 | static int evdev_ungrab(struct evdev *evdev, struct evdev_client *client) | 181 | static int evdev_ungrab(struct evdev *evdev, struct evdev_client *client) |
182 | { | 182 | { |
183 | if (evdev->grab != client) | 183 | struct evdev_client *grab = rcu_dereference_protected(evdev->grab, |
184 | lockdep_is_held(&evdev->mutex)); | ||
185 | |||
186 | if (grab != client) | ||
184 | return -EINVAL; | 187 | return -EINVAL; |
185 | 188 | ||
186 | rcu_assign_pointer(evdev->grab, NULL); | 189 | rcu_assign_pointer(evdev->grab, NULL); |
@@ -259,8 +262,7 @@ static int evdev_release(struct inode *inode, struct file *file) | |||
259 | struct evdev *evdev = client->evdev; | 262 | struct evdev *evdev = client->evdev; |
260 | 263 | ||
261 | mutex_lock(&evdev->mutex); | 264 | mutex_lock(&evdev->mutex); |
262 | if (evdev->grab == client) | 265 | evdev_ungrab(evdev, client); |
263 | evdev_ungrab(evdev, client); | ||
264 | mutex_unlock(&evdev->mutex); | 266 | mutex_unlock(&evdev->mutex); |
265 | 267 | ||
266 | evdev_detach_client(evdev, client); | 268 | evdev_detach_client(evdev, client); |