Message ID | 20230413064412.185040-1-zyytlz.wz@163.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/bridge: adv7511: fix use after free bug in adv7511_remove due to race condition | expand |
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index ddceafa7b637..e702a993fe6f 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -1349,6 +1349,10 @@ static void adv7511_remove(struct i2c_client *i2c) { struct adv7511 *adv7511 = i2c_get_clientdata(i2c); + if (i2c->irq) + devm_free_irq(&i2c->dev, i2c->irq, adv7511); + cancel_work_sync(&adv7511->hpd_work); + adv7511_uninit_regulators(adv7511); drm_bridge_remove(&adv7511->bridge);
In adv7511_probe, adv7511->hpd_work is bound with adv7511_hpd_work. adv7511_irq_process might be called to start the work. If we call adv7511_remove with an unfinished work. There may be a race condition. Here is the possible sequence: CPU0 CPU1 |adv7511_hpd_work adv7511_remove | cec_devnode_release | cec_unregister_adapter| cec_devnode_unregister| put_device(&devnode->dev);| cec_devnode_release | cec_delete_adapter | kfree(adap); | |cec_phys_addr_invalidate |//use adap Fix it by canceling the work before cleanup in adv7511_remove. This is the patch with new title in order to clarify the bug. Old patch is here. The root cause is the same as old one. https://lore.kernel.org/all/20230316160548.1566989-1-zyytlz.wz@163.com/ Fixes: 518cb7057a59 ("drm/bridge: adv7511: Use work_struct to defer hotplug handing to out of irq context") Signed-off-by: Zheng Wang <zyytlz.wz@163.com> --- drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 4 ++++ 1 file changed, 4 insertions(+)