[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20241124135709.3351371-18-sashal@kernel.org>
Date: Sun, 24 Nov 2024 08:56:51 -0500
From: Sasha Levin <sashal@...nel.org>
To: linux-kernel@...r.kernel.org,
stable@...r.kernel.org
Cc: Norbert van Bolhuis <nvbolhuis@...il.com>,
Kalle Valo <kvalo@...nel.org>,
Sasha Levin <sashal@...nel.org>,
arend.vanspriel@...adcom.com,
erick.archer@...look.com,
sebastian.reichel@...labora.com,
saikrishnag@...vell.com,
krzysztof.kozlowski@...aro.org,
jacobe.zang@...ion.com,
linux-wireless@...r.kernel.org,
brcm80211@...ts.linux.dev,
brcm80211-dev-list.pdl@...adcom.com
Subject: [PATCH AUTOSEL 4.19 18/21] wifi: brcmfmac: Fix oops due to NULL pointer dereference in brcmf_sdiod_sglist_rw()
From: Norbert van Bolhuis <nvbolhuis@...il.com>
[ Upstream commit 857282b819cbaa0675aaab1e7542e2c0579f52d7 ]
This patch fixes a NULL pointer dereference bug in brcmfmac that occurs
when a high 'sd_sgentry_align' value applies (e.g. 512) and a lot of queued SKBs
are sent from the pkt queue.
The problem is the number of entries in the pre-allocated sgtable, it is
nents = max(rxglom_size, txglom_size) + max(rxglom_size, txglom_size) >> 4 + 1.
Given the default [rt]xglom_size=32 it's actually 35 which is too small.
Worst case, the pkt queue can end up with 64 SKBs. This occurs when a new SKB
is added for each original SKB if tailroom isn't enough to hold tail_pad.
At least one sg entry is needed for each SKB. So, eventually the "skb_queue_walk loop"
in brcmf_sdiod_sglist_rw may run out of sg entries. This makes sg_next return
NULL and this causes the oops.
The patch sets nents to max(rxglom_size, txglom_size) * 2 to be able handle
the worst-case.
Btw. this requires only 64-35=29 * 16 (or 20 if CONFIG_NEED_SG_DMA_LENGTH) = 464
additional bytes of memory.
Signed-off-by: Norbert van Bolhuis <nvbolhuis@...il.com>
Signed-off-by: Kalle Valo <kvalo@...nel.org>
Link: https://patch.msgid.link/20241107132903.13513-1-nvbolhuis@gmail.com
Signed-off-by: Sasha Levin <sashal@...nel.org>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 710dc59c5d34d..532733db4de85 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -770,7 +770,7 @@ void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev)
nents = max_t(uint, BRCMF_DEFAULT_RXGLOM_SIZE,
sdiodev->settings->bus.sdio.txglomsz);
- nents += (nents >> 4) + 1;
+ nents *= 2;
WARN_ON(nents > sdiodev->max_segment_count);
--
2.43.0
Powered by blists - more mailing lists