dp_altmode_remove() cancels dp->work with cancel_work_sync(), but the typec bus clears alt->ops only after ->remove() has returned, so the dp_altmode_vdm(), dp_cable_altmode_vdm() and dp_altmode_attention() callbacks can still call schedule_work(&dp->work) after the cancel. dp is devm-allocated on the partner altmode device and is freed once the unbind completes; a re-queued dp_altmode_work() may then run on freed memory. Fix this by disabling the work instead of only cancelling it. disable_work_sync() drains an in-flight dp_altmode_work() and keeps the work item disabled, so the late schedule_work() calls are rejected. The work is still drained before the plug reference is dropped. A later probe initializes a new work item, and the remove path holds no lock that dp_altmode_work() takes, so waiting cannot deadlock. This issue was found by an in-house static analysis tool. Fixes: 0e3bb7d6894d ("usb: typec: Add driver for DisplayPort alternate mode") Cc: stable@vger.kernel.org # v6.10+ Co-developed-by: Song Li Signed-off-by: Song Li Signed-off-by: Fan Wu --- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/typec/altmodes/displayport.c b/drivers/usb/typec/altmodes/displayport.c index d96ab106a980..f7b3566d4029 100644 @@ -815,7 +815,7 @@ { struct dp_altmode *dp = typec_altmode_get_drvdata(alt); - cancel_work_sync(&dp->work); + disable_work_sync(&dp->work); typec_altmode_put_plug(dp->plug_prime); if (dp->connector_fwnode) {