[PATCH net 2/2] net: cpsw: cancel RX mode work on probe failure
From: Karl Mehltretter
Date: Sat Oct 03 2026 - 10:11:10 EST
The legacy CPSW driver registers its netdevs before requesting their IRQs.
Once registered, an interface can be opened and dev_set_rx_mode() can queue
its rx_mode_work. If a later IRQ request fails, the probe error path
unregisters the interfaces but does not drain their work before returning.
Driver core then releases the devm-allocated netdevs and private data,
allowing a worker to dereference freed memory.
Call disable_work_sync() after unregistering each registered netdev. This
matches cpsw_remove(). It drains the work before the error path releases
the remaining resources.
Without this change, a QEMU stub test reproduced a use-after-free
after an IRQ request failure with rx_mode_work pending. KASAN reported:
BUG: KASAN: slab-use-after-free in cpsw_ndo_set_rx_mode_work+0x28/0x174
Workqueue: events cpsw_ndo_set_rx_mode_work
Call trace:
kasan_report from cpsw_ndo_set_rx_mode_work+0x28/0x174
cpsw_ndo_set_rx_mode_work from process_scheduled_works+0x4ac/0x790
process_scheduled_works from worker_thread+0x49c/0x5b0
Real hardware was not tested.
Fixes: 0b8c878d1173 ("net: cpsw: Execute ndo_set_rx_mode callback in a work queue")
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@xxxxxxxxx>
---
drivers/net/ethernet/ti/cpsw.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 4fc59f9f23fc..d93d94eaac2d 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -1766,9 +1766,15 @@ static int cpsw_probe(struct platform_device *pdev)
return 0;
clean_unregister_netdev_ret:
- if (secondary_registered)
+ if (secondary_registered) {
+ struct cpsw_priv *priv_sl2;
+
+ priv_sl2 = netdev_priv(cpsw->slaves[1].ndev);
unregister_netdev(cpsw->slaves[1].ndev);
+ disable_work_sync(&priv_sl2->rx_mode_work);
+ }
unregister_netdev(ndev);
+ disable_work_sync(&priv->rx_mode_work);
clean_cpts:
cpts_release(cpsw->cpts);
cpdma_ctlr_destroy(cpsw->dma);
--
2.53.0