summaryrefslogtreecommitdiff
path: root/drivers/media/usb
diff options
context:
space:
mode:
authorMatthias Schwarzott <zzam@gentoo.org>2017-08-02 19:46:00 +0300
committerMauro Carvalho Chehab <mchehab@s-opensource.com>2017-08-27 13:33:47 +0300
commite59eb4adf0d79fe7692c08c07445ec9efc8ddc1c (patch)
treec770a4bdb12f205cc26bb61a1bf7ad88abe4ccf9 /drivers/media/usb
parent412b16d623cf4fd794713f314db5aad10c46ad87 (diff)
downloadlinux-e59eb4adf0d79fe7692c08c07445ec9efc8ddc1c.tar.xz
media: cx231xx: fix use-after-free when unregistering the i2c_client for the dvb demod
Calling i2c_unregister_device for a demod driver destroys the frontend object. Later it is accessed by calling dvb_unregister_frontend and dvb_frontend_detach. In some cases this leads to a general protection fault with this callstack: dvb_unregister_frontend+0x25/0x50 [dvb_core] dvb_fini+0xdb/0x160 [cx231xx_dvb] cx231xx_unregister_extension+0x3d/0xb0 [cx231xx] cx231xx_dvb_unregister+0x10/0x809 [cx231xx_dvb] SyS_delete_module+0x18a/0x240 ? exit_to_usermode_loop+0x7b/0x80 entry_SYSCALL_64_fastpath+0x17/0x98 Signed-off-by: Matthias Schwarzott <zzam@gentoo.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Diffstat (limited to 'drivers/media/usb')
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-dvb.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c
index ee3eeeb600f8..c18bb33e060e 100644
--- a/drivers/media/usb/cx231xx/cx231xx-dvb.c
+++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c
@@ -585,6 +585,9 @@ static void unregister_dvb(struct cx231xx_dvb *dvb)
dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
dvb_dmxdev_release(&dvb->dmxdev);
dvb_dmx_release(&dvb->demux);
+ dvb_unregister_frontend(dvb->frontend);
+ dvb_frontend_detach(dvb->frontend);
+ dvb_unregister_adapter(&dvb->adapter);
/* remove I2C tuner */
client = dvb->i2c_client_tuner;
if (client) {
@@ -597,9 +600,6 @@ static void unregister_dvb(struct cx231xx_dvb *dvb)
module_put(client->dev.driver->owner);
i2c_unregister_device(client);
}
- dvb_unregister_frontend(dvb->frontend);
- dvb_frontend_detach(dvb->frontend);
- dvb_unregister_adapter(&dvb->adapter);
}
static int dvb_init(struct cx231xx *dev)