]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: brcmfmac: Fix potential kernel oops when probe fails
authorMarek Szyprowski <m.szyprowski@samsung.com>
Tue, 3 Feb 2026 10:21:33 +0000 (11:21 +0100)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 23 Feb 2026 08:24:30 +0000 (09:24 +0100)
When probe of the sdio brcmfmac device fails for some reasons (i.e.
missing firmware), the sdiodev->bus is set to error instead of NULL, thus
the cleanup later in brcmf_sdio_remove() tries to free resources via
invalid bus pointer. This happens because sdiodev->bus is set 2 times:
first in brcmf_sdio_probe() and second time in brcmf_sdiod_probe(). Fix
this by chaning the brcmf_sdio_probe() function to return the error code
and set sdio->bus only there.

Fixes: 0ff0843310b7 ("wifi: brcmfmac: Add optional lpo clock enable support")
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Acked-by: Arend van Spriel<arend.vanspriel@broadcom.com>
Link: https://patch.msgid.link/20260203102133.1478331-1-m.szyprowski@samsung.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h

index 6a3f187320fc41c300ccb515a04fb5d3e373000d..13952dfeb3e30cde82c3f0ae4f7a170f16528622 100644 (file)
@@ -951,11 +951,10 @@ int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)
                goto out;
 
        /* try to attach to the target device */
-       sdiodev->bus = brcmf_sdio_probe(sdiodev);
-       if (IS_ERR(sdiodev->bus)) {
-               ret = PTR_ERR(sdiodev->bus);
+       ret = brcmf_sdio_probe(sdiodev);
+       if (ret)
                goto out;
-       }
+
        brcmf_sdiod_host_fixup(sdiodev->func2->card->host);
 out:
        if (ret)
index 8cf9d7e7c3f70cde40953fced9d6b7396e793bbf..4e6ed02c159134f2684eb859c87ae30f7617a2e0 100644 (file)
@@ -4445,7 +4445,7 @@ brcmf_sdio_prepare_fw_request(struct brcmf_sdio *bus)
        return fwreq;
 }
 
-struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
+int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
 {
        int ret;
        struct brcmf_sdio *bus;
@@ -4551,11 +4551,12 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
                goto fail;
        }
 
-       return bus;
+       return 0;
 
 fail:
        brcmf_sdio_remove(bus);
-       return ERR_PTR(ret);
+       sdiodev->bus = NULL;
+       return ret;
 }
 
 /* Detach and free everything */
index 0d18ed15b4032a9925660384ff9918cd3f38e76b..80180d5c6c879aebb53adc6107e74a0db3ddc778 100644 (file)
@@ -358,7 +358,7 @@ void brcmf_sdiod_freezer_uncount(struct brcmf_sdio_dev *sdiodev);
 int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev);
 int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev);
 
-struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev);
+int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev);
 void brcmf_sdio_remove(struct brcmf_sdio *bus);
 void brcmf_sdio_isr(struct brcmf_sdio *bus, bool in_isr);