diff options
author | Guo Mengqi <guomengqi3@huawei.com> | 2024-04-09 10:26:47 +0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2024-04-13 12:50:16 +0200 |
commit | 4d0adb19dc8aba90f2298560fd65871f1afbd2ca (patch) | |
tree | 55bbd2ba3799cc8db4ce3163a3d720624fb7bf89 | |
parent | 7d303dee473ba3529d75b63491e9963342107bed (diff) | |
download | linux-stable-4d0adb19dc8aba90f2298560fd65871f1afbd2ca.tar.gz linux-stable-4d0adb19dc8aba90f2298560fd65871f1afbd2ca.tar.bz2 linux-stable-4d0adb19dc8aba90f2298560fd65871f1afbd2ca.zip |
drm/vkms: call drm_atomic_helper_shutdown before drm_dev_put()
commit 73a82b22963d ("drm/atomic: Fix potential use-after-free
in nonblocking commits") introduced drm_dev_get/put() to
drm_atomic_helper_shutdown(). And this cause problem in vkms driver exit
process.
vkms_exit()
drm_dev_put()
vkms_release()
drm_atomic_helper_shutdown()
drm_dev_get()
drm_dev_put()
vkms_release() ------ use after free
Using 5.4 stable x86 image on qemu, below stacktrace can be triggered by
load and unload vkms.ko.
root:~ # insmod vkms.ko
[ 76.957802] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
[ 76.961490] [drm] Driver supports precise vblank timestamp query.
[ 76.964416] [drm] Initialized vkms 1.0.0 20180514 for vkms on minor 0
root:~ # rmmod vkms.ko
[ 79.650202] refcount_t: addition on 0; use-after-free.
[ 79.650249] WARNING: CPU: 2 PID: 3533 at ../lib/refcount.c:25 refcount_warn_saturate+0xcf/0xf0
[ 79.654241] Modules linked in: vkms(-)
[ 79.654249] CPU: 2 PID: 3533 Comm: rmmod Not tainted 5.4.273 #4
[ 79.654251] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
[ 79.654262] RIP: 0010:refcount_warn_saturate+0xcf/0xf0
...
[ 79.654296] Call Trace:
[ 79.654462] ? __warn+0x80/0xd0
[ 79.654473] ? refcount_warn_saturate+0xcf/0xf0
[ 79.654481] ? report_bug+0xb6/0x130
[ 79.654484] ? refcount_warn_saturate+0xcf/0xf0
[ 79.654489] ? fixup_bug.part.12+0x13/0x30
[ 79.654492] ? do_error_trap+0x90/0xb0
[ 79.654495] ? do_invalid_op+0x31/0x40
[ 79.654497] ? refcount_warn_saturate+0xcf/0xf0
[ 79.654504] ? invalid_op+0x1e/0x30
[ 79.654508] ? refcount_warn_saturate+0xcf/0xf0
[ 79.654516] drm_atomic_state_init+0x68/0xb0
[ 79.654543] drm_atomic_state_alloc+0x43/0x60
[ 79.654551] drm_atomic_helper_disable_all+0x13/0x180
[ 79.654562] drm_atomic_helper_shutdown+0x5f/0xb0
[ 79.654571] vkms_release+0x18/0x40 [vkms]
[ 79.654575] vkms_exit+0x29/0xc00 [vkms]
[ 79.654582] __x64_sys_delete_module+0x155/0x220
[ 79.654592] do_syscall_64+0x43/0x120
[ 79.654603] entry_SYSCALL_64_after_hwframe+0x5c/0xc1
[ 79.654619] ---[ end trace ce0c02f57ea6bf73 ]---
It seems that the proper unload sequence is:
drm_atomic_helper_shutdown();
drm_dev_put();
Just put drm_atomic_helper_shutdown() before drm_dev_put()
should solve the problem.
Note that vkms exit code is refactored by commit 53d77aaa3f76
("drm/vkms: Use devm_drm_dev_alloc") in tags/v5.10-rc1.
So this bug only exists on 4.19 and 5.4.
Fixes: 380c7ceabdde ("drm/atomic: Fix potential use-after-free in nonblocking commits")
Fixes: 2ead1be54b22 ("drm/vkms: Fix connector leak at the module removal")
Signed-off-by: Guo Mengqi <guomengqi3@huawei.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/gpu/drm/vkms/vkms_drv.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c index b1201c18d3eb..d32e08f17427 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -39,7 +39,6 @@ static void vkms_release(struct drm_device *dev) struct vkms_device *vkms = container_of(dev, struct vkms_device, drm); platform_device_unregister(vkms->platform); - drm_atomic_helper_shutdown(&vkms->drm); drm_mode_config_cleanup(&vkms->drm); drm_dev_fini(&vkms->drm); } @@ -137,6 +136,7 @@ static void __exit vkms_exit(void) } drm_dev_unregister(&vkms_device->drm); + drm_atomic_helper_shutdown(&vkms_device->drm); drm_dev_put(&vkms_device->drm); kfree(vkms_device); |