On Sat Sep 12 22:05:54 2026 -0400, Myeonghun Pak wrote:
> The DVBSKY S950C, DVBSKY T980C and TechnoTrend CT2-4500 CI paths register
> the DVB bus before attaching their SP2 CI client. If that client cannot be
> created, bound, or pinned, the current error path removes the I2C frontend
> components and only deallocates the frontend list, leaving the registered
> DVB adapter behind. Removing an I2C demod before unregistering the DVB bus
> can also expose the use-after-free ordering fixed for the normal remove
> path.
>
> Unregister the DVB bus immediately when SP2 CI setup fails, before the
> existing I2C client cleanup. The bus helper empties the frontend list, so
> the later frontend deallocation has nothing left to release. Keep failures
> from vb2_dvb_register_bus() on the existing cleanup path. Also release an
> unbound SP2 client and propagate the actual I2C creation or CI registration
> error.
>
> This issue was identified during our ongoing static-analysis research while
> reviewing kernel code.
>
> Fixes: 2b0aac3011bc ("[media] cx23885: move CI/MAC registration to a separate
> function")
> Cc: [email protected]
> Assisted-by: OpenAI:GPT-5.6
> Co-developed-by: Ijae Kim <[email protected]>
> Signed-off-by: Ijae Kim <[email protected]>
> Signed-off-by: Myeonghun Pak <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>
Patch committed.
Thanks,
Hans Verkuil
drivers/media/pci/cx23885/cx23885-dvb.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
---
diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c
b/drivers/media/pci/cx23885/cx23885-dvb.c
index f240ccda40ed..348abde0ba26 100644
--- a/drivers/media/pci/cx23885/cx23885-dvb.c
+++ b/drivers/media/pci/cx23885/cx23885-dvb.c
@@ -1158,8 +1158,12 @@ static int dvb_register_ci_mac(struct cx23885_tsport
*port)
info.platform_data = &sp2_config;
request_module(info.type);
client_ci = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
- if (!i2c_client_has_driver(client_ci))
+ if (IS_ERR(client_ci))
+ return PTR_ERR(client_ci);
+ if (!client_ci->dev.driver) {
+ i2c_unregister_device(client_ci);
return -ENODEV;
+ }
if (!try_module_get(client_ci->dev.driver->owner)) {
i2c_unregister_device(client_ci);
return -ENODEV;
@@ -1202,7 +1206,7 @@ static int dvb_register(struct cx23885_tsport *port)
int (*p_set_voltage)(struct dvb_frontend *fe,
enum fe_sec_voltage voltage) = NULL;
int mfe_shared = 0; /* bus not shared by default */
- int ret;
+ int ret = -EINVAL;
/* Get the first frontend */
fe0 = vb2_dvb_get_frontend(&port->frontends, 1);
@@ -2586,8 +2590,10 @@ static int dvb_register(struct cx23885_tsport *port)
goto frontend_detach;
ret = dvb_register_ci_mac(port);
- if (ret)
+ if (ret) {
+ vb2_dvb_unregister_bus(&port->frontends);
goto frontend_detach;
+ }
return 0;
@@ -2618,7 +2624,7 @@ frontend_detach:
port->gate_ctrl = NULL;
vb2_dvb_dealloc_frontends(&port->frontends);
- return -EINVAL;
+ return ret;
}
int cx23885_dvb_register(struct cx23885_tsport *port)
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]