[PATCH] media: az6007: stop CA thread on probe failure
From: Yuanzhe Liu
Date: Tue Oct 13 2026 - 14:37:19 EST
From: YuanZhe Liu <25031212351@xxxxxxxxxxxxxxxxx>
During device initialization, az6007_frontend_attach() calls
az6007_ci_init() to start the EN50221 conditional access kernel
polling thread via dvb_ca_en50221_init().
However, if dvb_usbv2_probe() subsequently encounters a failure
(for instance, in tuner_attach or dvb_create_media_graph), it
enters the err_free_all error path in dvb_usb_core.c:
err_free_all:
dvb_usbv2_exit(d);
if (d->props->disconnect)
d->props->disconnect(d);
err_kfree_priv:
kfree(d->priv);
Because az6007_props does not set .disconnect, the active CA polling
thread is never stopped. When d->priv (struct az6007_device_state)
is freed, the still-running thread calls ca->pub->poll_slot_status()
which accesses the freed state, resulting in a slab-use-after-free
read or crash when dereferencing ca->data.
Assign az6007_ci_uninit to the .disconnect callback of both az6007_props
and az6007_cablestar_hdci_props. az6007_ci_uninit() invokes
dvb_ca_en50221_release() to terminate the polling thread and tear down
the CA interface before d->priv is freed. az6007_ci_uninit() is
idempotent because it checks state->ca.data before releasing and zeroes
the structure, so calling it from both the probe error path and normal
disconnect is safe.
Fixes: 962f8f67e486 ("[media] Add CI support to az6007 driver")
Cc: stable@xxxxxxxxxxxxxxx
Co-developed-by: Bin Yu <byu@xxxxxxxxxxxxx>
Signed-off-by: Bin Yu <byu@xxxxxxxxxxxxx>
Co-developed-by: Cheng Wen <wencheng@xxxxxxxxxxxxx>
Signed-off-by: Cheng Wen <wencheng@xxxxxxxxxxxxx>
Signed-off-by: YuanZhe Liu <25031212351@xxxxxxxxxxxxxxxxx>
---
drivers/media/usb/dvb-usb-v2/az6007.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/media/usb/dvb-usb-v2/az6007.c b/drivers/media/usb/dvb-usb-v2/az6007.c
index 65ef045b74ca..c4fdf437695c 100644
--- a/drivers/media/usb/dvb-usb-v2/az6007.c
+++ b/drivers/media/usb/dvb-usb-v2/az6007.c
@@ -906,6 +906,7 @@ static struct dvb_usb_device_properties az6007_props = {
.download_firmware = az6007_download_firmware,
.identify_state = az6007_identify_state,
.power_ctrl = az6007_power_ctrl,
+ .disconnect = az6007_ci_uninit,
.num_adapters = 1,
.adapter = {
{ .stream = DVB_USB_STREAM_BULK(0x02, 10, 4096), }
@@ -929,6 +930,7 @@ static struct dvb_usb_device_properties az6007_cablestar_hdci_props = {
.download_firmware = az6007_download_firmware,
.identify_state = az6007_identify_state,
.power_ctrl = az6007_power_ctrl,
+ .disconnect = az6007_ci_uninit,
.num_adapters = 1,
.adapter = {
{ .stream = DVB_USB_STREAM_BULK(0x02, 10, 4096), }
--
2.34.1