diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2009-08-24 05:46:30 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-08-28 14:40:41 -0400 |
commit | 77a980dc6c4674fc7741d72b9775135669318d8d (patch) | |
tree | be8a359a42002eda0553c0fe046a4a7f0e62e3a8 | |
parent | 0448b5fc032ea76096eb3cfbe3196b3c01b08b86 (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.c | 34 |
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 | } |
2535 | EXPORT_SYMBOL(ieee80211_rx); | 2531 | EXPORT_SYMBOL(ieee80211_rx); |
2536 | 2532 | ||