Skip to content

Commit fdfa59c

Browse files
StefanBruensmchehab
authored andcommitted
media: dvbsky: Avoid leaking dvb frontend
Commit 14f4eae ("media: dvbsky: fix driver unregister logic") fixed a use-after-free by removing the reference to the frontend after deleting the backing i2c device. This has the unfortunate side effect the frontend device is never freed in the dvb core leaving a dangling device, leading to errors when the dvb core tries to register the frontend after e.g. a replug as reported here: https://www.spinics.net/lists/linux-media/msg138181.html media: dvbsky: issues with DVBSky T680CI === [ 561.119145] sp2 8-0040: CIMaX SP2 successfully attached [ 561.119161] usb 2-3: DVB: registering adapter 0 frontend 0 (Silicon Labs Si2168)... [ 561.119174] sysfs: cannot create duplicate filename '/class/dvb/ dvb0.frontend0' === The use after free happened as dvb_usbv2_disconnect calls in this order: - dvb_usb_device::props->exit(...) - dvb_usbv2_adapter_frontend_exit(...) + if (fe) dvb_unregister_frontend(fe) + dvb_usb_device::props->frontend_detach(...) Moving the release of the i2c device from exit() to frontend_detach() avoids the dangling pointer access and allows the core to unregister the frontend. This was originally reported for a DVBSky T680CI, but it also affects the MyGica T230C. As all supported devices structure the registration/ unregistration identically, apply the change for all device types. Signed-off-by: Stefan Brüns <[email protected]> Signed-off-by: Sean Young <[email protected]> Signed-off-by: Mauro Carvalho Chehab <[email protected]>
1 parent ef4bb63 commit fdfa59c

File tree

1 file changed

+10
-8
lines changed

1 file changed

+10
-8
lines changed

drivers/media/usb/dvb-usb-v2/dvbsky.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -615,16 +615,18 @@ static int dvbsky_init(struct dvb_usb_device *d)
615615
return 0;
616616
}
617617

618-
static void dvbsky_exit(struct dvb_usb_device *d)
618+
static int dvbsky_frontend_detach(struct dvb_usb_adapter *adap)
619619
{
620+
struct dvb_usb_device *d = adap_to_d(adap);
620621
struct dvbsky_state *state = d_to_priv(d);
621-
struct dvb_usb_adapter *adap = &d->adapter[0];
622+
623+
dev_dbg(&d->udev->dev, "%s: adap=%d\n", __func__, adap->id);
622624

623625
dvb_module_release(state->i2c_client_tuner);
624626
dvb_module_release(state->i2c_client_demod);
625627
dvb_module_release(state->i2c_client_ci);
626628

627-
adap->fe[0] = NULL;
629+
return 0;
628630
}
629631

630632
/* DVB USB Driver stuff */
@@ -640,11 +642,11 @@ static struct dvb_usb_device_properties dvbsky_s960_props = {
640642

641643
.i2c_algo = &dvbsky_i2c_algo,
642644
.frontend_attach = dvbsky_s960_attach,
645+
.frontend_detach = dvbsky_frontend_detach,
643646
.init = dvbsky_init,
644647
.get_rc_config = dvbsky_get_rc_config,
645648
.streaming_ctrl = dvbsky_streaming_ctrl,
646649
.identify_state = dvbsky_identify_state,
647-
.exit = dvbsky_exit,
648650
.read_mac_address = dvbsky_read_mac_addr,
649651

650652
.num_adapters = 1,
@@ -667,11 +669,11 @@ static struct dvb_usb_device_properties dvbsky_s960c_props = {
667669

668670
.i2c_algo = &dvbsky_i2c_algo,
669671
.frontend_attach = dvbsky_s960c_attach,
672+
.frontend_detach = dvbsky_frontend_detach,
670673
.init = dvbsky_init,
671674
.get_rc_config = dvbsky_get_rc_config,
672675
.streaming_ctrl = dvbsky_streaming_ctrl,
673676
.identify_state = dvbsky_identify_state,
674-
.exit = dvbsky_exit,
675677
.read_mac_address = dvbsky_read_mac_addr,
676678

677679
.num_adapters = 1,
@@ -694,11 +696,11 @@ static struct dvb_usb_device_properties dvbsky_t680c_props = {
694696

695697
.i2c_algo = &dvbsky_i2c_algo,
696698
.frontend_attach = dvbsky_t680c_attach,
699+
.frontend_detach = dvbsky_frontend_detach,
697700
.init = dvbsky_init,
698701
.get_rc_config = dvbsky_get_rc_config,
699702
.streaming_ctrl = dvbsky_streaming_ctrl,
700703
.identify_state = dvbsky_identify_state,
701-
.exit = dvbsky_exit,
702704
.read_mac_address = dvbsky_read_mac_addr,
703705

704706
.num_adapters = 1,
@@ -721,11 +723,11 @@ static struct dvb_usb_device_properties dvbsky_t330_props = {
721723

722724
.i2c_algo = &dvbsky_i2c_algo,
723725
.frontend_attach = dvbsky_t330_attach,
726+
.frontend_detach = dvbsky_frontend_detach,
724727
.init = dvbsky_init,
725728
.get_rc_config = dvbsky_get_rc_config,
726729
.streaming_ctrl = dvbsky_streaming_ctrl,
727730
.identify_state = dvbsky_identify_state,
728-
.exit = dvbsky_exit,
729731
.read_mac_address = dvbsky_read_mac_addr,
730732

731733
.num_adapters = 1,
@@ -748,11 +750,11 @@ static struct dvb_usb_device_properties mygica_t230c_props = {
748750

749751
.i2c_algo = &dvbsky_i2c_algo,
750752
.frontend_attach = dvbsky_mygica_t230c_attach,
753+
.frontend_detach = dvbsky_frontend_detach,
751754
.init = dvbsky_init,
752755
.get_rc_config = dvbsky_get_rc_config,
753756
.streaming_ctrl = dvbsky_streaming_ctrl,
754757
.identify_state = dvbsky_identify_state,
755-
.exit = dvbsky_exit,
756758

757759
.num_adapters = 1,
758760
.adapter = {

0 commit comments

Comments
 (0)