diff options
| author | Daniil Dulov <d.dulov@aladdin.ru> | 2025-06-26 14:46:19 +0300 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2025-07-17 18:30:52 +0200 |
| commit | b24f65c184540dfb967479320ecf7e8c2e9220dc (patch) | |
| tree | 5c5eb6b1aae525ea46264194342246b6e50c486c | |
| parent | 09064e6d659729d01742744efecd9131cdd93c24 (diff) | |
| download | linux-b24f65c184540dfb967479320ecf7e8c2e9220dc.tar.gz linux-b24f65c184540dfb967479320ecf7e8c2e9220dc.tar.bz2 linux-b24f65c184540dfb967479320ecf7e8c2e9220dc.zip | |
wifi: zd1211rw: Fix potential NULL pointer dereference in zd_mac_tx_to_dev()
[ Upstream commit 74b1ec9f5d627d2bdd5e5b6f3f81c23317657023 ]
There is a potential NULL pointer dereference in zd_mac_tx_to_dev(). For
example, the following is possible:
T0 T1
zd_mac_tx_to_dev()
/* len == skb_queue_len(q) */
while (len > ZD_MAC_MAX_ACK_WAITERS) {
filter_ack()
spin_lock_irqsave(&q->lock, flags);
/* position == skb_queue_len(q) */
for (i=1; i<position; i++)
skb = __skb_dequeue(q)
if (mac->type == NL80211_IFTYPE_AP)
skb = __skb_dequeue(q);
spin_unlock_irqrestore(&q->lock, flags);
skb_dequeue() -> NULL
Since there is a small gap between checking skb queue length and skb being
unconditionally dequeued in zd_mac_tx_to_dev(), skb_dequeue() can return NULL.
Then the pointer is passed to zd_mac_tx_status() where it is dereferenced.
In order to avoid potential NULL pointer dereference due to situations like
above, check if skb is not NULL before passing it to zd_mac_tx_status().
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: 459c51ad6e1f ("zd1211rw: port to mac80211")
Signed-off-by: Daniil Dulov <d.dulov@aladdin.ru>
Link: https://patch.msgid.link/20250626114619.172631-1-d.dulov@aladdin.ru
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
| -rw-r--r-- | drivers/net/wireless/zydas/zd1211rw/zd_mac.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/net/wireless/zydas/zd1211rw/zd_mac.c b/drivers/net/wireless/zydas/zd1211rw/zd_mac.c index 3ef8533205f9..0a7f368f0d99 100644 --- a/drivers/net/wireless/zydas/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zydas/zd1211rw/zd_mac.c @@ -583,7 +583,11 @@ void zd_mac_tx_to_dev(struct sk_buff *skb, int error) skb_queue_tail(q, skb); while (skb_queue_len(q) > ZD_MAC_MAX_ACK_WAITERS) { - zd_mac_tx_status(hw, skb_dequeue(q), + skb = skb_dequeue(q); + if (!skb) + break; + + zd_mac_tx_status(hw, skb, mac->ack_pending ? mac->ack_signal : 0, NULL); mac->ack_pending = 0; |
