Skip to content

Commit 4a215aa

Browse files
dtortorvalds
authored andcommitted
Input: fix use-after-free introduced with dynamic minor changes
Commit 7f8d4ca ("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 <[email protected]> Signed-off-by: Dmitry Torokhov <[email protected]> Acked-by: Al Viro <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 2f0157f commit 4a215aa

File tree

3 files changed

+3
-6
lines changed

3 files changed

+3
-6
lines changed

drivers/input/evdev.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,6 @@ static int evdev_release(struct inode *inode, struct file *file)
292292
kfree(client);
293293

294294
evdev_close_device(evdev);
295-
put_device(&evdev->dev);
296295

297296
return 0;
298297
}
@@ -331,7 +330,6 @@ static int evdev_open(struct inode *inode, struct file *file)
331330
file->private_data = client;
332331
nonseekable_open(inode, file);
333332

334-
get_device(&evdev->dev);
335333
return 0;
336334

337335
err_free_client:
@@ -1001,6 +999,7 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
1001999
goto err_free_evdev;
10021000

10031001
cdev_init(&evdev->cdev, &evdev_fops);
1002+
evdev->cdev.kobj.parent = &evdev->dev.kobj;
10041003
error = cdev_add(&evdev->cdev, evdev->dev.devt, 1);
10051004
if (error)
10061005
goto err_unregister_handle;

drivers/input/joydev.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,6 @@ static int joydev_release(struct inode *inode, struct file *file)
243243
kfree(client);
244244

245245
joydev_close_device(joydev);
246-
put_device(&joydev->dev);
247246

248247
return 0;
249248
}
@@ -270,7 +269,6 @@ static int joydev_open(struct inode *inode, struct file *file)
270269
file->private_data = client;
271270
nonseekable_open(inode, file);
272271

273-
get_device(&joydev->dev);
274272
return 0;
275273

276274
err_free_client:
@@ -858,6 +856,7 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
858856
goto err_free_joydev;
859857

860858
cdev_init(&joydev->cdev, &joydev_fops);
859+
joydev->cdev.kobj.parent = &joydev->dev.kobj;
861860
error = cdev_add(&joydev->cdev, joydev->dev.devt, 1);
862861
if (error)
863862
goto err_unregister_handle;

drivers/input/mousedev.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,6 @@ static int mousedev_release(struct inode *inode, struct file *file)
523523
kfree(client);
524524

525525
mousedev_close_device(mousedev);
526-
put_device(&mousedev->dev);
527526

528527
return 0;
529528
}
@@ -558,7 +557,6 @@ static int mousedev_open(struct inode *inode, struct file *file)
558557
file->private_data = client;
559558
nonseekable_open(inode, file);
560559

561-
get_device(&mousedev->dev);
562560
return 0;
563561

564562
err_free_client:
@@ -892,6 +890,7 @@ static struct mousedev *mousedev_create(struct input_dev *dev,
892890
}
893891

894892
cdev_init(&mousedev->cdev, &mousedev_fops);
893+
mousedev->cdev.kobj.parent = &mousedev->dev.kobj;
895894
error = cdev_add(&mousedev->cdev, mousedev->dev.devt, 1);
896895
if (error)
897896
goto err_unregister_handle;

0 commit comments

Comments
 (0)