[PATCH v4 4/6] phy: cpcap-usb: add extcon support
sashiko-bot at kernel.org
sashiko-bot at kernel.org
Sat Jul 11 10:14:31 PDT 2026
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
New issues:
- [Medium] The ordering of extcon state updates exposes invalid intermediate cable states to userspace.
Pre-existing issues:
- [High] Pre-existing UAF: Delayed work can be re-armed after cancel_delayed_work_sync() during driver removal due to an IRQ thread race.
--
--- Patch [4]: [PATCH v4 4/6] phy: cpcap-usb: add extcon support ---
commit 5fa6aab542d92a2c79fbe5195a861859976507b6
Author: Ivaylo Dimitrov <ivo.g.dimitrov.75 at gmail.com>
phy: cpcap-usb: add extcon support
This commit registers an Extcon device and reports the detected USB cable
state. It exports this state through the Extcon framework so other drivers
can consume it using standard kernel interfaces.
> diff --git a/drivers/phy/motorola/phy-cpcap-usb.c b/drivers/phy/motorola/phy-cpcap-usb.c
> index d4eb8086b6000..8f9bea1d8a212 100644
> --- a/drivers/phy/motorola/phy-cpcap-usb.c
> +++ b/drivers/phy/motorola/phy-cpcap-usb.c
[ ... ]
> @@ -226,6 +239,46 @@ static void cpcap_usb_try_musb_mailbox(struct cpcap_phy_ddata *ddata,
> __func__, error);
> }
>
> +static void cpcap_usb_set_extcon(struct cpcap_phy_ddata *ddata)
> +{
> + int cable;
> +
> + switch (ddata->mode) {
[ ... ]
> + if (cable == ddata->cable)
> + return;
> +
> + if (ddata->cable == EXTCON_CHG_USB_SDP)
> + extcon_set_state_sync(ddata->edev, EXTCON_USB, false);
> + else if (cable == EXTCON_CHG_USB_SDP)
> + extcon_set_state_sync(ddata->edev, EXTCON_USB, true);
> +
> + if (ddata->cable != EXTCON_NONE)
> + extcon_set_state_sync(ddata->edev, ddata->cable, false);
[Severity: Medium]
Could this ordering expose invalid intermediate cable states to userspace?
When transitioning to a new cable state (specifically EXTCON_CHG_USB_SDP),
the new state's associated EXTCON_USB state is enabled before the old
ddata->cable state is cleared.
Because extcon_set_state_sync() immediately notifies consumers and emits a
uevent, consumers might briefly observe overlapping, mutually exclusive
states (such as both DCP and SDP active simultaneously).
Would it be safer to completely clear the old states before asserting any
new states?
> +
> + if (cable != EXTCON_NONE)
> + extcon_set_state_sync(ddata->edev, cable, true);
> +
> + ddata->cable = cable;
> +}
[ ... ]
[Severity: High]
This is a pre-existing issue, but I noticed a potential use-after-free race
involving the delayed work during driver unbind. Does this execution sequence
leave the work queued after removal?
If the IRQ thread checks ddata->active and gets preempted before calling
schedule_delayed_work():
cpcap_phy_irq_thread() {
...
if (atomic_read(&ddata->active))
... <preempted here> ...
cpcap_usb_phy_remove() can concurrently set active to 0 and call
cancel_delayed_work_sync(). Since the work isn't queued yet, the
cancellation completes immediately:
cpcap_usb_phy_remove() {
...
atomic_set(&ddata->active, 0);
cancel_delayed_work_sync(&ddata->detect_work);
...
During devres cleanup, free_irq() waits for the IRQ thread to finish.
The thread then resumes, unconditionally calls schedule_delayed_work(),
and exits:
schedule_delayed_work(&ddata->detect_work, msecs_to_jiffies(1));
}
After free_irq() completes, devres frees ddata. The delayed work will
subsequently execute and access the freed memory.
Could this be prevented by disabling IRQs prior to cancelling the work?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260711164754.185565-1-ivo.g.dimitrov.75@gmail.com?part=4
More information about the linux-phy
mailing list