diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-10-22 02:57:20 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-22 07:50:37 +0200 |
commit | 4a215aade0baa0487d4644d7aef6f166c84c516e (patch) | |
tree | 3cf126e431235d21fdf565e2d39089397680e803 /drivers/input/joydev.c | |
parent | char_dev: pin parent kobject (diff) | |
download | linux-4a215aade0baa0487d4644d7aef6f166c84c516e.tar.xz linux-4a215aade0baa0487d4644d7aef6f166c84c516e.zip |
Input: fix use-after-free introduced with dynamic minor changes
Commit 7f8d4cad1e4e ("Input: extend the number of event (and other)
devices") made evdev, joydev and mousedev to embed struct cdev into
their respective structures representing input devices.
Unfortunately character device structure may outlive the parent
structure unless we do not set it up as parent of character device so
that it will stay pinned until character device is freed.
Also, now that parent structure is pinned while character device exists
we do not need to pin and unpin it every time user opens or closes it.
Reported-by: Dave Jones <davej@redhat.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Acked-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/input/joydev.c')
-rw-r--r-- | drivers/input/joydev.c | 3 |
1 files changed, 1 insertions, 2 deletions
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index b62b5891f399..f362883c94e3 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -243,7 +243,6 @@ static int joydev_release(struct inode *inode, struct file *file) kfree(client); joydev_close_device(joydev); - put_device(&joydev->dev); return 0; } @@ -270,7 +269,6 @@ static int joydev_open(struct inode *inode, struct file *file) file->private_data = client; nonseekable_open(inode, file); - get_device(&joydev->dev); return 0; err_free_client: @@ -858,6 +856,7 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev, goto err_free_joydev; cdev_init(&joydev->cdev, &joydev_fops); + joydev->cdev.kobj.parent = &joydev->dev.kobj; error = cdev_add(&joydev->cdev, joydev->dev.devt, 1); if (error) goto err_unregister_handle; |