Re: BUG: use-after-free bisected to "usb: typec: class: fix typec_altmode_put_partner to put plugs"

From: Christian A. Ehrhardt
Date: Sun Dec 24 2023 - 07:15:12 EST



Hi Chris,

[ Cc: linux-usb@xxxxxxxxxxxxxxx ]

On Sun, Dec 24, 2023 at 12:54:11AM +0000, Chris Bainbridge wrote:
> Hello,
>
> A use-after-free error has appeared after a recent commit. This occurs
> when I unplug the USB-C dock (HP G5).
>
>
> b17b7fe6dd5c6ff74b38b0758ca799cdbb79e26e is the first bad commit
> commit b17b7fe6dd5c6ff74b38b0758ca799cdbb79e26e
> Author: RD Babiera <rdbabiera@xxxxxxxxxx>
> Date: Wed Nov 29 19:23:50 2023 +0000
>
> usb: typec: class: fix typec_altmode_put_partner to put plugs

I'm not very familiar with the code in question but the double
free seems rather obvious to me as typec_altmode_put_partner()
frees the altmode itself (which is already being releasee) and not
the partner.

I think this might fix it. Can you give it a try? If it does I can
cook up a proper patch later this week.

regards Christian

diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
index 16a670828dde..2da19feacd91 100644
--- a/drivers/usb/typec/class.c
+++ b/drivers/usb/typec/class.c
@@ -263,11 +263,13 @@ static void typec_altmode_put_partner(struct altmode *altmode)
{
struct altmode *partner = altmode->partner;
struct typec_altmode *adev;
+ struct typec_altmode *partner_adev;

if (!partner)
return;

adev = &altmode->adev;
+ partner_adev = &partner->adev;

if (is_typec_plug(adev->dev.parent)) {
struct typec_plug *plug = to_typec_plug(adev->dev.parent);
@@ -276,7 +278,7 @@ static void typec_altmode_put_partner(struct altmode *altmode)
} else {
partner->partner = NULL;
}
- put_device(&adev->dev);
+ put_device(&partner_adev->dev);
}

/**