Commit 243307a0 authored by Marek Szyprowski's avatar Marek Szyprowski Committed by Johannes Berg
Browse files

wifi: brcmfmac: Fix potential kernel oops when probe fails



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: 0ff08433 ("wifi: brcmfmac: Add optional lpo clock enable support")
Signed-off-by: default avatarMarek Szyprowski <m.szyprowski@samsung.com>
Acked-by: default avatarArend van <Spriel&lt;arend.vanspriel@broadcom.com>
Link: https://patch.msgid.link/20260203102133.1478331-1-m.szyprowski@samsung.com


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent c854758a
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -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)
+4 −3
Original line number Diff line number Diff line
@@ -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 */
+1 −1
Original line number Diff line number Diff line
@@ -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);