On Mon, Mar 11, 2024 at 02:52:19PM +0800, Xu Yang wrote: > When unregister pd capabilitie in tcpm, KASAN will capture below double > -free issue. The root cause is the same capabilitiy will be kfreed twice, > the first time is kfreed by pd_capabilities_release() and the second time > is explicitly kfreed by tcpm_port_unregister_pd(). > > [ 3.988059] BUG: KASAN: double-free in tcpm_port_unregister_pd+0x1a4/0x3dc > [ 3.995001] Free of addr ffff0008164d3000 by task kworker/u16:0/10 > [ 4.001206] > [ 4.002712] CPU: 2 PID: 10 Comm: kworker/u16:0 Not tainted 6.8.0-rc5-next-20240220-05616-g52728c567a55 #53 > [ 4.012402] Hardware name: Freescale i.MX8QXP MEK (DT) > [ 4.017569] Workqueue: events_unbound deferred_probe_work_func > [ 4.023456] Call trace: > [ 4.025920] dump_backtrace+0x94/0xec > [ 4.029629] show_stack+0x18/0x24 > [ 4.032974] dump_stack_lvl+0x78/0x90 > [ 4.036675] print_report+0xfc/0x5c0 > [ 4.040289] kasan_report_invalid_free+0xa0/0xc0 > [ 4.044937] __kasan_slab_free+0x124/0x154 > [ 4.049072] kfree+0xb4/0x1e8 > [ 4.052069] tcpm_port_unregister_pd+0x1a4/0x3dc > [ 4.056725] tcpm_register_port+0x1dd0/0x2558 > [ 4.061121] tcpci_register_port+0x420/0x71c > [ 4.065430] tcpci_probe+0x118/0x2e0 > > To fix the issue, this will remove kree() from tcpm_port_unregister_pd(). > > Fixes: cd099cde4ed2 ("usb: typec: tcpm: Support multiple capabilities") > cc: <stable@xxxxxxxxxxxxxxx> > Suggested-by: Aisheng Dong <aisheng.dong@xxxxxxx> > Signed-off-by: Xu Yang <xu.yang_2@xxxxxxx> Acked-by: Heikki Krogerus <heikki.krogerus@xxxxxxxxxxxxxxx> > --- > drivers/usb/typec/tcpm/tcpm.c | 2 -- > 1 file changed, 2 deletions(-) > > diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c > index 3d505614bff1..afbb0d832db2 100644 > --- a/drivers/usb/typec/tcpm/tcpm.c > +++ b/drivers/usb/typec/tcpm/tcpm.c > @@ -6940,9 +6940,7 @@ static void tcpm_port_unregister_pd(struct tcpm_port *port) > port->port_source_caps = NULL; > for (i = 0; i < port->pd_count; i++) { > usb_power_delivery_unregister_capabilities(port->pd_list[i]->sink_cap); > - kfree(port->pd_list[i]->sink_cap); > usb_power_delivery_unregister_capabilities(port->pd_list[i]->source_cap); > - kfree(port->pd_list[i]->source_cap); > devm_kfree(port->dev, port->pd_list[i]); > port->pd_list[i] = NULL; > usb_power_delivery_unregister(port->pds[i]); > -- > 2.34.1 -- heikki