media: dvbsky: fix driver unregister logic
authorMauro Carvalho Chehab <mchehab@s-opensource.com>
Thu, 8 Mar 2018 18:47:39 +0000 (13:47 -0500)
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>
Fri, 4 May 2018 14:55:12 +0000 (10:55 -0400)
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 [ffff8803a6f61100ffff8803a6f61900)
[  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>
drivers/media/usb/dvb-usb-v2/dvbsky.c

index 416231bf381f29165d716c7fe6b83ab87e818f94..e28bd8836751e46e9ee4a1209d953b374dc2bde2 100644 (file)
@@ -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 */