]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: brcmfmac: Fix potential use-after-free issue when stopping watchdog task
authorMarek Szyprowski <m.szyprowski@samsung.com>
Thu, 16 Apr 2026 09:33:39 +0000 (11:33 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 27 Apr 2026 10:37:54 +0000 (12:37 +0200)
Watchdog task might end between send_sig() and kthread_stop() calls, what
results in the use-after-free issue. Fix this by increasing watchdog task
reference count before calling send_sig() and dropping it by switching to
kthread_stop_put().

Cc: stable@vger.kernel.org
Fixes: 373c83a801f1 ("brcmfmac: stop watchdog before detach and free everything")
Fixes: a9ffda88be74 ("brcm80211: fmac: abstract bus_stop interface function pointer")
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Link: https://patch.msgid.link/20260416093339.2066829-1-m.szyprowski@samsung.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c

index 30f6fcb6863279802ecc2731c46df2244bd96d88..8fb595733b9c3603f5a12184c0b6cfdc9af0027b 100644 (file)
@@ -2476,8 +2476,9 @@ static void brcmf_sdio_bus_stop(struct device *dev)
        brcmf_dbg(TRACE, "Enter\n");
 
        if (bus->watchdog_tsk) {
+               get_task_struct(bus->watchdog_tsk);
                send_sig(SIGTERM, bus->watchdog_tsk, 1);
-               kthread_stop(bus->watchdog_tsk);
+               kthread_stop_put(bus->watchdog_tsk);
                bus->watchdog_tsk = NULL;
        }
 
@@ -4567,8 +4568,9 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus)
        if (bus) {
                /* Stop watchdog task */
                if (bus->watchdog_tsk) {
+                       get_task_struct(bus->watchdog_tsk);
                        send_sig(SIGTERM, bus->watchdog_tsk, 1);
-                       kthread_stop(bus->watchdog_tsk);
+                       kthread_stop_put(bus->watchdog_tsk);
                        bus->watchdog_tsk = NULL;
                }