[PATCH v3 1/4] drm/bridge: it6505: cancel outstanding work before teardown in remove()
From: Daniel Golle
Date: Mon Jul 20 2026 - 22:28:17 EST
it6505_i2c_remove() tears down the bridge and frees its state without
cancelling any of the driver's background work. struct it6505 is
allocated with devm_drm_bridge_alloc(), so devres frees it as soon as
remove() returns; link_works, hdcp_wait_ksv_list, hdcp_work and
extcon_wq can all still be pending or running at that point and will
then dereference freed memory.
link_works and extcon_wq are flushed in it6505_bridge_detach(), but
that only runs if DRM core calls the bridge's .detach() before the
i2c client is unbound -- not guaranteed if the i2c driver is unbound
independently of the DRM device that consumes it. hdcp_wait_ksv_list
and hdcp_work are never cancelled anywhere.
Cancel all four synchronously in remove() itself so teardown is safe
regardless of ordering. cancel_work_sync() on extcon_wq is safe even
when it was never INIT_WORK()'d, since it6505 is zero-allocated and a
zeroed work_struct is reported as not pending.
Fixes: b5c84a9edcd4 ("drm/bridge: add it6505 driver")
Signed-off-by: Daniel Golle <daniel@xxxxxxxxxxxxxx>
---
v3: new patch, split out to fix a pre-existing use-after-free flagged
by automated review of v2's audio series; needed before that
series adds another cancel_delayed_work_sync() call next to the
ones this commit is adding.
drivers/gpu/drm/bridge/ite-it6505.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c
index 8ecb43611dba..2f349aefb705 100644
--- a/drivers/gpu/drm/bridge/ite-it6505.c
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
@@ -3644,6 +3644,10 @@ static void it6505_i2c_remove(struct i2c_client *client)
{
struct it6505 *it6505 = i2c_get_clientdata(client);
+ cancel_work_sync(&it6505->link_works);
+ cancel_work_sync(&it6505->hdcp_wait_ksv_list);
+ cancel_delayed_work_sync(&it6505->hdcp_work);
+ cancel_work_sync(&it6505->extcon_wq);
drm_bridge_remove(&it6505->bridge);
drm_dp_aux_unregister(&it6505->aux);
it6505_debugfs_remove(it6505);
--
2.55.0