[PATCH] media: dvb-usb-v2: az6007: Release CA interface on frontend detach
From: YuanZhe Liu
Date: Tue Oct 13 2026 - 23:05:09 EST
During device initialization in dvb_usbv2_probe(), the driver calls
az6007_frontend_attach() which invokes az6007_ci_init() to initialize
the EN50221 Conditional Access (CA) interface via dvb_ca_en50221_init().
This starts a background monitoring kernel thread named "kdvb-ca-%d:%d".
If a subsequent initialization step fails in dvb_usbv2_init(), the probe
routine branches to err_free_all, calling dvb_usbv2_exit() and then freeing
d->priv via kfree(d->priv).
However, az6007_props and az6007_cablestar_hdci_props do not define a
.frontend_detach callback. Consequently, dvb_usbv2_adapter_frontend_exit()
skips tearing down the CA interface. The background CA monitoring thread
continues running and attempts to dereference ca->pub in
dvb_ca_en50221_check_camstatus(), accessing the already freed d->priv
memory, which triggers a slab-use-after-free or a crash due to an invalid
instruction fetch:
BUG: unable to handle page fault for address: 000001a400000001
#PF: supervisor instruction fetch in kernel mode
RIP: 0010:0x1a400000001
Call Trace:
dvb_ca_en50221_check_camstatus+0x107/0x310
dvb_ca_en50221_thread_state_machine+0x31/0xb40
dvb_ca_en50221_thread+0x12a/0x180
kthread+0x106/0x220
Fix this by implementing az6007_frontend_detach() to call
az6007_ci_uninit(), which stops the kernel thread and releases the
CA interface before d->priv is freed.
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 | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/media/usb/dvb-usb-v2/az6007.c b/drivers/media/usb/dvb-usb-v2/az6007.c
index 65ef045b74ca..cff27708da3a 100644
--- a/drivers/media/usb/dvb-usb-v2/az6007.c
+++ b/drivers/media/usb/dvb-usb-v2/az6007.c
@@ -609,6 +609,14 @@ static int az6007_ci_init(struct dvb_usb_adapter *adap)
return 0;
}
+static int az6007_frontend_detach(struct dvb_usb_adapter *adap)
+{
+ struct dvb_usb_device *d = adap_to_d(adap);
+
+ az6007_ci_uninit(d);
+ return 0;
+}
+
static int az6007_read_mac_addr(struct dvb_usb_adapter *adap, u8 mac[6])
{
struct dvb_usb_device *d = adap_to_d(adap);
@@ -900,6 +908,7 @@ static struct dvb_usb_device_properties az6007_props = {
.i2c_algo = &az6007_i2c_algo,
.tuner_attach = az6007_tuner_attach,
.frontend_attach = az6007_frontend_attach,
+ .frontend_detach = az6007_frontend_detach,
.streaming_ctrl = az6007_streaming_ctrl,
.get_rc_config = az6007_get_rc_config,
.read_mac_address = az6007_read_mac_addr,
@@ -922,6 +931,7 @@ static struct dvb_usb_device_properties az6007_cablestar_hdci_props = {
.i2c_algo = &az6007_i2c_algo,
.tuner_attach = az6007_tuner_attach,
.frontend_attach = az6007_cablestar_hdci_frontend_attach,
+ .frontend_detach = az6007_frontend_detach,
.streaming_ctrl = az6007_streaming_ctrl,
/* ditch get_rc_config as it can't work (TS35 remote, I believe it's rc5) */
.get_rc_config = NULL,
--
2.34.1