6.1-stable review patch. If anyone has any objections, please let me know. ------------------ From: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> In commit cfcd544a9974 ("usb: typec: tcpm: unregister existing source caps before re-registration"), quilt, and git, applied the diff to the incorrect function, which would cause bad problems if exercised in a device with these capabilities. Fix this all up (including the follow-up fix in commit 4053696594d7 ("usb: typec: tcpm: fix use-after-free case in tcpm_register_source_caps") to be in the correct function. Fixes: 4053696594d7 ("usb: typec: tcpm: fix use-after-free case in tcpm_register_source_caps") Fixes: cfcd544a9974 ("usb: typec: tcpm: unregister existing source caps before re-registration") Reported-by: Charles Yo <charlesyo@xxxxxxxxxx> Cc: Kyle Tso <kyletso@xxxxxxxxxx> Cc: Amit Sunil Dhamne <amitsd@xxxxxxxxxx> Cc: Ondrej Jirman <megi@xxxxxx> Cc: Heikki Krogerus <heikki.krogerus@xxxxxxxxxxxxxxx> Cc: Dmitry Baryshkov <dmitry.baryshkov@xxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/usb/typec/tcpm/tcpm.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c @@ -2397,7 +2397,7 @@ static int tcpm_register_source_caps(str { struct usb_power_delivery_desc desc = { port->negotiated_rev }; struct usb_power_delivery_capabilities_desc caps = { }; - struct usb_power_delivery_capabilities *cap; + struct usb_power_delivery_capabilities *cap = port->partner_source_caps; if (!port->partner_pd) port->partner_pd = usb_power_delivery_register(NULL, &desc); @@ -2407,6 +2407,11 @@ static int tcpm_register_source_caps(str memcpy(caps.pdo, port->source_caps, sizeof(u32) * port->nr_source_caps); caps.role = TYPEC_SOURCE; + if (cap) { + usb_power_delivery_unregister_capabilities(cap); + port->partner_source_caps = NULL; + } + cap = usb_power_delivery_register_capabilities(port->partner_pd, &caps); if (IS_ERR(cap)) return PTR_ERR(cap); @@ -2420,7 +2425,7 @@ static int tcpm_register_sink_caps(struc { struct usb_power_delivery_desc desc = { port->negotiated_rev }; struct usb_power_delivery_capabilities_desc caps = { }; - struct usb_power_delivery_capabilities *cap = port->partner_source_caps; + struct usb_power_delivery_capabilities *cap; if (!port->partner_pd) port->partner_pd = usb_power_delivery_register(NULL, &desc); @@ -2430,11 +2435,6 @@ static int tcpm_register_sink_caps(struc memcpy(caps.pdo, port->sink_caps, sizeof(u32) * port->nr_sink_caps); caps.role = TYPEC_SINK; - if (cap) { - usb_power_delivery_unregister_capabilities(cap); - port->partner_source_caps = NULL; - } - cap = usb_power_delivery_register_capabilities(port->partner_pd, &caps); if (IS_ERR(cap)) return PTR_ERR(cap);