diff options
author | Mauro Carvalho Chehab <mchehab@s-opensource.com> | 2018-03-08 13:47:39 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | 2018-05-04 10:55:12 -0400 |
commit | 14f4eaeddabce65deba2e1346efccf80f666f7b7 (patch) | |
tree | 6eb4ee8e5be40fbdf29a59340c0fbc3fb14750bd /drivers/media | |
parent | 2c7e3ca8fb1b5cda5387686e2da2931ec62b1ada (diff) |
media: dvbsky: fix driver unregister logic
There's a user-after-free there, if the frontend is attached
via the new I2C way:
[ 112.539806] usbcore: deregistering interface driver dvb_usb_dvbsky
[ 112.568489] ==================================================================
[ 112.568600] BUG: KASAN: use-after-free in dvb_unregister_frontend+0x18/0xb0 [dvb_core]
[ 112.568610] Read of size 8 at addr ffff8803a6f61530 by task rmmod/2246
[ 112.568622] CPU: 0 PID: 2246 Comm: rmmod Not tainted 4.16.0-rc4+ #103
[ 112.568624] Hardware name: /NUC5i7RYB, BIOS RYBDWi35.86A.0364.2017.0511.0949 05/11/2017
[ 112.568625] Call Trace:
[ 112.568631] dump_stack+0x5c/0x7c
[ 112.568636] print_address_description+0x6a/0x270
[ 112.568640] kasan_report+0x258/0x380
[ 112.568657] ? dvb_unregister_frontend+0x18/0xb0 [dvb_core]
[ 112.568673] dvb_unregister_frontend+0x18/0xb0 [dvb_core]
[ 112.568681] dvb_usbv2_exit+0x156/0x4a0 [dvb_usb_v2]
[ 112.568689] dvb_usbv2_disconnect+0xa0/0x140 [dvb_usb_v2]
[ 112.568694] usb_unbind_interface+0xd8/0x3f0
[ 112.568700] device_release_driver_internal+0x1ce/0x2f0
[ 112.568705] driver_detach+0x66/0xc0
[ 112.568709] bus_remove_driver+0x86/0x150
[ 112.568713] usb_deregister+0x90/0x180
[ 112.568718] SyS_delete_module+0x293/0x330
[ 112.568721] ? free_module+0x330/0x330
[ 112.568725] ? _cond_resched+0x16/0x50
[ 112.568729] ? task_work_run+0x7d/0xd0
[ 112.568732] ? mem_cgroup_handle_over_high+0x1c/0xc0
[ 112.568736] ? free_module+0x330/0x330
[ 112.568740] do_syscall_64+0xe7/0x250
[ 112.568744] entry_SYSCALL_64_after_hwframe+0x3d/0xa2
[ 112.568747] RIP: 0033:0x7facafa272a7
[ 112.568749] RSP: 002b:00007fffdea14cc8 EFLAGS: 00000206 ORIG_RAX: 00000000000000b0
[ 112.568753] RAX: ffffffffffffffda RBX: 00007fffdea14d28 RCX: 00007facafa272a7
[ 112.568755] RDX: 000000000000000a RSI: 0000000000000800 RDI: 00005599557337c8
[ 112.568756] RBP: 0000559955733760 R08: 000000000000000a R09: 0000000000000000
[ 112.568758] R10: 00007facafaa0280 R11: 0000000000000206 R12: 00007fffdea14ef0
[ 112.568761] R13: 00007fffdea16eac R14: 0000559955733260 R15: 0000559955733760
[ 112.568808] Allocated by task 638:
[ 112.568816] kasan_kmalloc+0xa0/0xd0
[ 112.568820] kmem_cache_alloc_trace+0x114/0x230
[ 112.568826] m88ds3103_probe+0x9a/0x643 [m88ds3103]
[ 112.568830] i2c_device_probe+0x2e9/0x3c0
[ 112.568833] driver_probe_device+0x46e/0x6a0
[ 112.568836] bus_for_each_drv+0xd6/0x130
[ 112.568838] __device_attach+0x166/0x1f0
[ 112.568841] bus_probe_device+0xea/0x110
[ 112.568844] device_add+0x6a3/0x9f0
[ 112.568847] i2c_new_device+0x28f/0x5c0
[ 112.568861] dvb_module_probe+0x91/0x110 [dvb_core]
[ 112.568867] dvbsky_s960c_attach+0x1c4/0x460 [dvb_usb_dvbsky]
[ 112.568873] dvb_usbv2_probe+0x1191/0x1950 [dvb_usb_v2]
[ 112.568877] usb_probe_interface+0x1b3/0x430
[ 112.568880] driver_probe_device+0x46e/0x6a0
[ 112.568882] __driver_attach+0xeb/0x110
[ 112.568885] bus_for_each_dev+0xe4/0x140
[ 112.568888] bus_add_driver+0x249/0x380
[ 112.568891] driver_register+0xc6/0x170
[ 112.568893] usb_register_driver+0xec/0x200
[ 112.568896] do_one_initcall+0x8f/0x1ee
[ 112.568900] do_init_module+0xde/0x320
[ 112.568902] load_module+0x3ed0/0x4850
[ 112.568905] SYSC_finit_module+0x192/0x1c0
[ 112.568908] do_syscall_64+0xe7/0x250
[ 112.568911] entry_SYSCALL_64_after_hwframe+0x3d/0xa2
[ 112.568916] Freed by task 2246:
[ 112.568923] __kasan_slab_free+0x136/0x180
[ 112.568925] kfree+0xa5/0x1e0
[ 112.568931] m88ds3103_remove+0x42/0x60 [m88ds3103]
[ 112.568934] i2c_device_remove+0x72/0xd0
[ 112.568937] device_release_driver_internal+0x1ce/0x2f0
[ 112.568940] bus_remove_device+0x197/0x270
[ 112.568942] device_del+0x239/0x550
[ 112.568945] device_unregister+0x16/0x70
[ 112.568949] dvbsky_exit+0x4c/0x70 [dvb_usb_dvbsky]
[ 112.568955] dvb_usbv2_disconnect+0x98/0x140 [dvb_usb_v2]
[ 112.568958] usb_unbind_interface+0xd8/0x3f0
[ 112.568961] device_release_driver_internal+0x1ce/0x2f0
[ 112.568964] driver_detach+0x66/0xc0
[ 112.568967] bus_remove_driver+0x86/0x150
[ 112.568970] usb_deregister+0x90/0x180
[ 112.568973] SyS_delete_module+0x293/0x330
[ 112.568976] do_syscall_64+0xe7/0x250
[ 112.568979] entry_SYSCALL_64_after_hwframe+0x3d/0xa2
[ 112.568985] The buggy address belongs to the object at ffff8803a6f61100
which belongs to the cache kmalloc-2048 of size 2048
[ 112.568998] The buggy address is located 1072 bytes inside of
2048-byte region [ffff8803a6f61100, ffff8803a6f61900)
[ 112.569008] The buggy address belongs to the page:
[ 112.569015] page:ffffea000e9bd800 count:1 mapcount:0 mapping:0000000000000000 index:0x0 compound_mapcount: 0
[ 112.569025] flags: 0x17ffe000008100(slab|head)
[ 112.569034] raw: 0017ffe000008100 0000000000000000 0000000000000000 00000001000f000f
[ 112.569044] raw: ffffea000ee2d000 0000000500000005 ffff880407002a80 0000000000000000
[ 112.569053] page dumped because: kasan: bad access detected
[ 112.569062] Memory state around the buggy address:
[ 112.569070] ffff8803a6f61400: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 112.569079] ffff8803a6f61480: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 112.569088] >ffff8803a6f61500: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 112.569095] ^
[ 112.569103] ffff8803a6f61580: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 112.569112] ffff8803a6f61600: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 112.569119] ==================================================================
[ 112.569127] Disabling lock debugging due to kernel taint
[ 112.571161] dvb_usb_v2: 'DVBSky S960CI:2-2' successfully deinitialized and disconnected
Fix it by letting the dvb-usb-v2 core to know that the frontend
was already removed.
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/usb/dvb-usb-v2/dvbsky.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/media/usb/dvb-usb-v2/dvbsky.c b/drivers/media/usb/dvb-usb-v2/dvbsky.c index 416231bf381f..e28bd8836751 100644 --- a/drivers/media/usb/dvb-usb-v2/dvbsky.c +++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c @@ -618,10 +618,13 @@ static int dvbsky_init(struct dvb_usb_device *d) static void dvbsky_exit(struct dvb_usb_device *d) { struct dvbsky_state *state = d_to_priv(d); + struct dvb_usb_adapter *adap = &d->adapter[0]; dvb_module_release(state->i2c_client_tuner); dvb_module_release(state->i2c_client_demod); dvb_module_release(state->i2c_client_ci); + + adap->fe[0] = NULL; } /* DVB USB Driver stuff */ |