From 77a980dc6c4674fc7741d72b9775135669318d8d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 24 Aug 2009 11:46:30 +0200 Subject: [PATCH] mac80211: fix RX skb leaks In mac80211's RX path some of the warnings that warn about drivers passing invalid status values leak the skb, fix that by refactoring the code. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/rx.c | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index b98f1afbfebf..c01588f9d453 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2447,17 +2447,13 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) struct ieee80211_supported_band *sband; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); - if (status->band < 0 || - status->band >= IEEE80211_NUM_BANDS) { - WARN_ON(1); - return; - } + if (WARN_ON(status->band < 0 || + status->band >= IEEE80211_NUM_BANDS)) + goto drop; sband = local->hw.wiphy->bands[status->band]; - if (!sband) { - WARN_ON(1); - return; - } + if (WARN_ON(!sband)) + goto drop; /* * If we're suspending, it is possible although not too likely @@ -2466,25 +2462,21 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) * that might, for example, cause stations to be added or other * driver callbacks be invoked. */ - if (unlikely(local->quiescing || local->suspended)) { - kfree_skb(skb); - return; - } + if (unlikely(local->quiescing || local->suspended)) + goto drop; /* * The same happens when we're not even started, * but that's worth a warning. */ - if (WARN_ON(!local->started)) { - kfree_skb(skb); - return; - } + if (WARN_ON(!local->started)) + goto drop; if (status->flag & RX_FLAG_HT) { /* rate_idx is MCS index */ if (WARN_ON(status->rate_idx < 0 || status->rate_idx >= 76)) - return; + goto drop; /* HT rates are not in the table - use the highest legacy rate * for now since other parts of mac80211 may not yet be fully * MCS aware. */ @@ -2492,7 +2484,7 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) } else { if (WARN_ON(status->rate_idx < 0 || status->rate_idx >= sband->n_bitrates)) - return; + goto drop; rate = &sband->bitrates[status->rate_idx]; } @@ -2531,6 +2523,10 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) __ieee80211_rx_handle_packet(hw, skb, rate); rcu_read_unlock(); + + return; + drop: + kfree_skb(skb); } EXPORT_SYMBOL(ieee80211_rx); -- 2.30.2