[PATCH] usb: typec: altmodes/displayport: Disable work before dp is freed
From: Fan Wu
Date: Tue Sep 22 2026 - 23:01:28 EST
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@xxxxxxxxxxxxxxx # v6.10+
Co-developed-by: Song Li <songl@xxxxxxxxxx>
Signed-off-by: Song Li <songl@xxxxxxxxxx>
Signed-off-by: Fan Wu <fanwu01@xxxxxxxxxx>
---
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) {