aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-08-24 05:46:30 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-08-28 14:40:41 -0400
commit77a980dc6c4674fc7741d72b9775135669318d8d (patch)
treebe8a359a42002eda0553c0fe046a4a7f0e62e3a8
parent0448b5fc032ea76096eb3cfbe3196b3c01b08b86 (diff)
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 <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--net/mac80211/rx.c34
1 files 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)
2447 struct ieee80211_supported_band *sband; 2447 struct ieee80211_supported_band *sband;
2448 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 2448 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
2449 2449
2450 if (status->band < 0 || 2450 if (WARN_ON(status->band < 0 ||
2451 status->band >= IEEE80211_NUM_BANDS) { 2451 status->band >= IEEE80211_NUM_BANDS))
2452 WARN_ON(1); 2452 goto drop;
2453 return;
2454 }
2455 2453
2456 sband = local->hw.wiphy->bands[status->band]; 2454 sband = local->hw.wiphy->bands[status->band];
2457 if (!sband) { 2455 if (WARN_ON(!sband))
2458 WARN_ON(1); 2456 goto drop;
2459 return;
2460 }
2461 2457
2462 /* 2458 /*
2463 * If we're suspending, it is possible although not too likely 2459 * 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)
2466 * that might, for example, cause stations to be added or other 2462 * that might, for example, cause stations to be added or other
2467 * driver callbacks be invoked. 2463 * driver callbacks be invoked.
2468 */ 2464 */
2469 if (unlikely(local->quiescing || local->suspended)) { 2465 if (unlikely(local->quiescing || local->suspended))
2470 kfree_skb(skb); 2466 goto drop;
2471 return;
2472 }
2473 2467
2474 /* 2468 /*
2475 * The same happens when we're not even started, 2469 * The same happens when we're not even started,
2476 * but that's worth a warning. 2470 * but that's worth a warning.
2477 */ 2471 */
2478 if (WARN_ON(!local->started)) { 2472 if (WARN_ON(!local->started))
2479 kfree_skb(skb); 2473 goto drop;
2480 return;
2481 }
2482 2474
2483 if (status->flag & RX_FLAG_HT) { 2475 if (status->flag & RX_FLAG_HT) {
2484 /* rate_idx is MCS index */ 2476 /* rate_idx is MCS index */
2485 if (WARN_ON(status->rate_idx < 0 || 2477 if (WARN_ON(status->rate_idx < 0 ||
2486 status->rate_idx >= 76)) 2478 status->rate_idx >= 76))
2487 return; 2479 goto drop;
2488 /* HT rates are not in the table - use the highest legacy rate 2480 /* HT rates are not in the table - use the highest legacy rate
2489 * for now since other parts of mac80211 may not yet be fully 2481 * for now since other parts of mac80211 may not yet be fully
2490 * MCS aware. */ 2482 * MCS aware. */
@@ -2492,7 +2484,7 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
2492 } else { 2484 } else {
2493 if (WARN_ON(status->rate_idx < 0 || 2485 if (WARN_ON(status->rate_idx < 0 ||
2494 status->rate_idx >= sband->n_bitrates)) 2486 status->rate_idx >= sband->n_bitrates))
2495 return; 2487 goto drop;
2496 rate = &sband->bitrates[status->rate_idx]; 2488 rate = &sband->bitrates[status->rate_idx];
2497 } 2489 }
2498 2490
@@ -2531,6 +2523,10 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
2531 __ieee80211_rx_handle_packet(hw, skb, rate); 2523 __ieee80211_rx_handle_packet(hw, skb, rate);
2532 2524
2533 rcu_read_unlock(); 2525 rcu_read_unlock();
2526
2527 return;
2528 drop:
2529 kfree_skb(skb);
2534} 2530}
2535EXPORT_SYMBOL(ieee80211_rx); 2531EXPORT_SYMBOL(ieee80211_rx);
2536 2532