[PATCH] net: atheros: atl1: Fix use-after-free in atl1_remove due to race condition

From: Pei Xiao

Date: Mon Aug 03 2026 - 23:03:08 EST


In atl1_probe, &adapter->reset_dev_task is bound with
atl1_reset_dev_task, and &adapter->link_chg_task is bound with
atlx_link_chg_task. atl1_intr (on PHY link down, DMA errors or link
events) and atlx_tx_timeout can schedule these works on system_wq.

If we remove the device, atl1_remove makes cleanup and the memory
allocated for adapter with netdev_priv() is released by free_netdev(),
while the works mentioned above may still be pending or running. The
sequence of operations that may lead to a UAF bug is as follows:

CPU0 CPU1

| atl1_intr
| schedule_work(&adapter->reset_dev_task)
atl1_remove |
iowrite16(0, adapter->hw.hw_addr + |
REG_PHY_ENABLE) |
unregister_netdev(netdev) |
// ndo_stop -> atl1_close -> atl1_down |
// -> free_irq (IRQ handler stopped) |
pci_iounmap(pdev, adapter->hw.hw_addr) |
pci_release_regions(pdev) |
free_netdev(netdev) |
// adapter is freed |
| atl1_reset_dev_task
| // use adapter (use-after-free)

Fix it by canceling the works after the sources that can schedule
them (IRQ handler atl1_intr and the kernel netdev watchdog, which
calls atlx_tx_timeout) have been stopped, and before proceeding with
the remaining cleanup in atl1_remove.

Fixes: f3cc28c79760 ("Add Attansic L1 ethernet driver.")
Assisted-by: Codex:deepseek-v4-flash
Signed-off-by: Pei Xiao <xiaopei01@xxxxxxxxxx>
---
drivers/net/ethernet/atheros/atlx/atl1.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/drivers/net/ethernet/atheros/atlx/atl1.c b/drivers/net/ethernet/atheros/atlx/atl1.c
index 98a4d089270e..bb5a1d61c52c 100644
--- a/drivers/net/ethernet/atheros/atlx/atl1.c
+++ b/drivers/net/ethernet/atheros/atlx/atl1.c
@@ -3142,6 +3142,10 @@ static void atl1_remove(struct pci_dev *pdev)

iowrite16(0, adapter->hw.hw_addr + REG_PHY_ENABLE);
unregister_netdev(netdev);
+
+ cancel_work_sync(&adapter->reset_dev_task);
+ cancel_work_sync(&adapter->link_chg_task);
+
pci_iounmap(pdev, adapter->hw.hw_addr);
pci_release_regions(pdev);
free_netdev(netdev);
--
2.25.1