On Mon Aug 24 19:21:15 2026 +0530, Piyush Patle wrote:
> dvb_register_frontend() keeps two references to the frontend. One is
> released by dvb_unregister_frontend(), and the other by
> dvb_frontend_detach(). vidtv only called dvb_unregister_frontend(), so
> the second reference was never released. As a result,
> __dvb_frontend_free() was never called, leaking the frontend private
> data and its struct dvb_device.
> 
> The detach call was removed by commit 63101b756893 ("media: vidtv: fix
> driver unbind/remove") because it caused an OOPS. The demod .release
> callback freed vidtv_demod_state, and the I2C remove callbacks then
> accessed the freed state.
> 
> That commit also removed those accesses from the I2C remove callbacks.
> Restore the detach call, but remove the demod .release callback.
> vidtv_demod_state is owned by the I2C client and is already freed by
> vidtv_demod_i2c_remove(), so the frontend detach path should not free
> it.
> 
> Tested with kmemleak and KASAN over 10 bind/unbind cycles. The reported
> frontend and dvb_device leaks were present before the fix and were gone
> after it, with no KASAN reports.
> 
> Reported-by: [email protected]
> Closes: https://syzkaller.appspot.com/bug?extid=32f018fd65e799f79ae0
> Fixes: 63101b756893 ("media: vidtv: fix driver unbind/remove")
> Cc: [email protected]
> Tested-by: [email protected]
> Signed-off-by: Piyush Patle <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>

Patch committed.

Thanks,
Hans Verkuil

 drivers/media/test-drivers/vidtv/vidtv_bridge.c | 2 ++
 drivers/media/test-drivers/vidtv/vidtv_demod.c  | 9 ---------
 2 files changed, 2 insertions(+), 9 deletions(-)

---

diff --git a/drivers/media/test-drivers/vidtv/vidtv_bridge.c 
b/drivers/media/test-drivers/vidtv/vidtv_bridge.c
index fd69b4ee16f4..9887860b0198 100644
--- a/drivers/media/test-drivers/vidtv/vidtv_bridge.c
+++ b/drivers/media/test-drivers/vidtv/vidtv_bridge.c
@@ -474,6 +474,7 @@ fail_dmx:
 fail_demod_probe:
        for (i = i - 1; i >= 0; --i) {
                dvb_unregister_frontend(dvb->fe[i]);
+               dvb_frontend_detach(dvb->fe[i]);
 fail_fe:
                dvb_module_release(dvb->i2c_client_tuner[i]);
 fail_tuner_probe:
@@ -552,6 +553,7 @@ static void vidtv_bridge_remove(struct platform_device 
*pdev)
 
        for (i = 0; i < NUM_FE; ++i) {
                dvb_unregister_frontend(dvb->fe[i]);
+               dvb_frontend_detach(dvb->fe[i]);
                dvb_module_release(dvb->i2c_client_tuner[i]);
                dvb_module_release(dvb->i2c_client_demod[i]);
        }
diff --git a/drivers/media/test-drivers/vidtv/vidtv_demod.c 
b/drivers/media/test-drivers/vidtv/vidtv_demod.c
index 6e5fe402976b..3aa586004638 100644
--- a/drivers/media/test-drivers/vidtv/vidtv_demod.c
+++ b/drivers/media/test-drivers/vidtv/vidtv_demod.c
@@ -343,13 +343,6 @@ static int vidtv_diseqc_send_burst(struct dvb_frontend *fe,
        return 0;
 }
 
-static void vidtv_demod_release(struct dvb_frontend *fe)
-{
-       struct vidtv_demod_state *state = fe->demodulator_priv;
-
-       kfree(state);
-}
-
 static const struct dvb_frontend_ops vidtv_demod_ops = {
        .delsys = {
                SYS_DVBT,
@@ -390,8 +383,6 @@ static const struct dvb_frontend_ops vidtv_demod_ops = {
                        FE_CAN_HIERARCHY_AUTO,
        },
 
-       .release = vidtv_demod_release,
-
        .set_frontend = vidtv_demod_set_frontend,
        .get_frontend = vidtv_demod_get_frontend,
 
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to