On Wed Apr 22 20:17:34 2026 +0530, Deepanshu Kartikey wrote:
> cancel_delayed_work_sync() is called before i2c_mux_del_adapters()
> in rtl2832_remove(). While the cancel waits for any running instance
> of i2c_gate_work to finish, it does not prevent the timer from being
> rescheduled by a concurrent thread.
> 
> During probe, the r820t_attach() call attempts I2C transfers through
> the mux adapter. These transfers go through i2c_mux_master_xfer(),
> which calls rtl2832_deselect() after the transfer completes,
> rescheduling i2c_gate_work via schedule_delayed_work(). If this
> transfer is still in flight when rtl2832_remove() runs,
> rtl2832_deselect() can reschedule i2c_gate_work after it has been
> cancelled, causing a use-after-free when kfree(dev) is called.
> 
> Fix this by calling i2c_mux_del_adapters() before
> cancel_delayed_work_sync(). Once the mux adapter is unregistered, no
> new I2C transfers can go through it, so rtl2832_deselect() can no
> longer reschedule i2c_gate_work. The subsequent
> cancel_delayed_work_sync() is then guaranteed to be final.
> 
> Fixes: cddcc40b1b15 ("[media] rtl2832: convert to use an explicit i2c mux 
> core")
> Cc: [email protected]
> Reported-by: [email protected]
> Closes: https://syzkaller.appspot.com/bug?extid=019ced393ab913002b75
> Signed-off-by: Deepanshu Kartikey <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>

Patch committed.

Thanks,
Hans Verkuil

 drivers/media/dvb-frontends/rtl2832.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

---

diff --git a/drivers/media/dvb-frontends/rtl2832.c 
b/drivers/media/dvb-frontends/rtl2832.c
index d8e1546aea5e..9898f729304a 100644
--- a/drivers/media/dvb-frontends/rtl2832.c
+++ b/drivers/media/dvb-frontends/rtl2832.c
@@ -1115,10 +1115,10 @@ static void rtl2832_remove(struct i2c_client *client)
 
        dev_dbg(&client->dev, "\n");
 
-       cancel_delayed_work_sync(&dev->i2c_gate_work);
-
        i2c_mux_del_adapters(dev->muxc);
 
+       cancel_delayed_work_sync(&dev->i2c_gate_work);
+
        regmap_exit(dev->regmap);
 
        kfree(dev);
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to