Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

media: ddbridge: fix teardown/deregistration order in ddb_input_detach()

Brought to attention by Matthias Schwarzott <zzam@gentoo.org> by fixing
possible use-after-free faults in some demod drivers:

In ddb_input_detach(), the i2c_client is unregistered and removed before
dvb frontends are unregistered and detached. While no use-after-free issue
was observed so far, there is another issue with this:

dvb->attached keeps track of the state of the input/output registration,
and the i2c_client unregistration takes place only if everything was
successful (dvb->attached == 0x31). If for some reason an error occurred
during the frontend setup, that value stays at 0x20. In the following
error handling and cleanup, ddb_input_detach() will skip down to that
state, leaving the i2c_client registered, causing refcount issues.

Fix this by moving the i2c_client deregistration down to case 0x20.

Cc: Matthias Schwarzott <zzam@gentoo.org>
Signed-off-by: Daniel Scheller <d.scheller@gmx.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>

authored by

Daniel Scheller and committed by
Mauro Carvalho Chehab
1502efd2 6b852620

+6 -5
+6 -5
drivers/media/pci/ddbridge/ddbridge-core.c
··· 1255 1255 1256 1256 switch (dvb->attached) { 1257 1257 case 0x31: 1258 - client = dvb->i2c_client[0]; 1259 - if (client) { 1260 - module_put(client->dev.driver->owner); 1261 - i2c_unregister_device(client); 1262 - } 1263 1258 if (dvb->fe2) 1264 1259 dvb_unregister_frontend(dvb->fe2); 1265 1260 if (dvb->fe) ··· 1268 1273 dvb->fe = dvb->fe2 = NULL; 1269 1274 /* fallthrough */ 1270 1275 case 0x20: 1276 + client = dvb->i2c_client[0]; 1277 + if (client) { 1278 + module_put(client->dev.driver->owner); 1279 + i2c_unregister_device(client); 1280 + } 1281 + 1271 1282 dvb_net_release(&dvb->dvbnet); 1272 1283 /* fallthrough */ 1273 1284 case 0x12: