ipw_priv::qos_activate (handler ipw_bg_qos_activate) is scheduled on the system workqueue from the QoS association/probe-response paths (ipw_qos_association_resp(), ipw_handle_assoc_response()) via schedule_work(&priv->qos_activate). ipw_pci_remove() cancels ~two dozen other priv works with cancel_work_sync()/cancel_delayed_work_sync() (associate, disassociate, scan, rf_kill, roam, link_up/down, led_*, merge_networks, ...) but never cancels qos_activate. The driver has no private workqueue, so the work runs on the system workqueue and is not drained by any destroy_workqueue() at teardown either. If a qos_activate work is still pending when the device is removed, ipw_pci_remove() goes on to free_irq(), free the libipw/netdev and kfree(priv); the worker then dereferences the freed priv (ipw_bg_qos_activate(): priv->mutex, priv->status, priv->assoc_network -> ipw_qos_activate()) = use-after-free. Cancel qos_activate alongside the other works in ipw_pci_remove(). The handler takes priv->mutex and does not reschedule qos_activate, and this cancel is not performed under priv->mutex, so cancel_work_sync() neither deadlocks nor races a re-arm. Found by code review; not reproduced. Trigger needs a QoS association/probe-response frame racing device unbind. Same class as commit (atm: fore200e) "fix use-after-free in tasklets during device removal" and CVE-2024-27052 (wifi: rtl8xxxu): a teardown path that omits cancelling an async callback racing the object free. Signed-off-by: HyunjungKo --- drivers/net/wireless/intel/ipw2x00/ipw2200.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c --- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c @@ -11786,5 +11786,6 @@ static void ipw_pci_remove(struct pci_dev *pdev) cancel_delayed_work_sync(&priv->led_link_off); cancel_delayed_work_sync(&priv->led_act_off); cancel_work_sync(&priv->merge_networks); + cancel_work_sync(&priv->qos_activate); /* Free MAC hash list for ADHOC */ -- 2.43.0