Re: [PATCH] usb: typec: altmodes/displayport: Disable work before dp is freed
From: Heikki Krogerus
Date: Mon Sep 28 2026 - 09:41:02 EST
On Wed, Sep 23, 2026 at 02:46:37AM +0000, Fan Wu wrote:
> 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>
Reviewed-by: Heikki Krogerus <heikki.krogerus@xxxxxxxxxxxxxxx>
> ---
> 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) {
--
heikki