diff options
| -rw-r--r-- | net/mac80211/work.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/net/mac80211/work.c b/net/mac80211/work.c index 4c7de72c27e7..ad0bf5828140 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #define IEEE80211_MAX_PROBE_TRIES 5 | 32 | #define IEEE80211_MAX_PROBE_TRIES 5 |
| 33 | 33 | ||
| 34 | enum work_action { | 34 | enum work_action { |
| 35 | WORK_ACT_MISMATCH, | ||
| 35 | WORK_ACT_NONE, | 36 | WORK_ACT_NONE, |
| 36 | WORK_ACT_TIMEOUT, | 37 | WORK_ACT_TIMEOUT, |
| 37 | WORK_ACT_DONE, | 38 | WORK_ACT_DONE, |
| @@ -584,7 +585,7 @@ ieee80211_rx_mgmt_auth(struct ieee80211_work *wk, | |||
| 584 | u16 auth_alg, auth_transaction, status_code; | 585 | u16 auth_alg, auth_transaction, status_code; |
| 585 | 586 | ||
| 586 | if (wk->type != IEEE80211_WORK_AUTH) | 587 | if (wk->type != IEEE80211_WORK_AUTH) |
| 587 | return WORK_ACT_NONE; | 588 | return WORK_ACT_MISMATCH; |
| 588 | 589 | ||
| 589 | if (len < 24 + 6) | 590 | if (len < 24 + 6) |
| 590 | return WORK_ACT_NONE; | 591 | return WORK_ACT_NONE; |
| @@ -635,6 +636,9 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_work *wk, | |||
| 635 | struct ieee802_11_elems elems; | 636 | struct ieee802_11_elems elems; |
| 636 | u8 *pos; | 637 | u8 *pos; |
| 637 | 638 | ||
| 639 | if (wk->type != IEEE80211_WORK_ASSOC) | ||
| 640 | return WORK_ACT_MISMATCH; | ||
| 641 | |||
| 638 | /* | 642 | /* |
| 639 | * AssocResp and ReassocResp have identical structure, so process both | 643 | * AssocResp and ReassocResp have identical structure, so process both |
| 640 | * of them in this function. | 644 | * of them in this function. |
| @@ -690,6 +694,12 @@ ieee80211_rx_mgmt_probe_resp(struct ieee80211_work *wk, | |||
| 690 | 694 | ||
| 691 | ASSERT_WORK_MTX(local); | 695 | ASSERT_WORK_MTX(local); |
| 692 | 696 | ||
| 697 | if (wk->type != IEEE80211_WORK_DIRECT_PROBE) | ||
| 698 | return WORK_ACT_MISMATCH; | ||
| 699 | |||
| 700 | if (len < 24 + 12) | ||
| 701 | return WORK_ACT_NONE; | ||
| 702 | |||
| 693 | baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; | 703 | baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; |
| 694 | if (baselen > len) | 704 | if (baselen > len) |
| 695 | return WORK_ACT_NONE; | 705 | return WORK_ACT_NONE; |
| @@ -704,7 +714,7 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local, | |||
| 704 | struct ieee80211_rx_status *rx_status; | 714 | struct ieee80211_rx_status *rx_status; |
| 705 | struct ieee80211_mgmt *mgmt; | 715 | struct ieee80211_mgmt *mgmt; |
| 706 | struct ieee80211_work *wk; | 716 | struct ieee80211_work *wk; |
| 707 | enum work_action rma = WORK_ACT_NONE; | 717 | enum work_action rma; |
| 708 | u16 fc; | 718 | u16 fc; |
| 709 | 719 | ||
| 710 | rx_status = (struct ieee80211_rx_status *) skb->cb; | 720 | rx_status = (struct ieee80211_rx_status *) skb->cb; |
| @@ -751,7 +761,17 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local, | |||
| 751 | break; | 761 | break; |
| 752 | default: | 762 | default: |
| 753 | WARN_ON(1); | 763 | WARN_ON(1); |
| 764 | rma = WORK_ACT_NONE; | ||
| 754 | } | 765 | } |
| 766 | |||
| 767 | /* | ||
| 768 | * We've either received an unexpected frame, or we have | ||
| 769 | * multiple work items and need to match the frame to the | ||
| 770 | * right one. | ||
| 771 | */ | ||
| 772 | if (rma == WORK_ACT_MISMATCH) | ||
| 773 | continue; | ||
| 774 | |||
| 755 | /* | 775 | /* |
| 756 | * We've processed this frame for that work, so it can't | 776 | * We've processed this frame for that work, so it can't |
| 757 | * belong to another work struct. | 777 | * belong to another work struct. |
| @@ -761,6 +781,9 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local, | |||
| 761 | } | 781 | } |
| 762 | 782 | ||
| 763 | switch (rma) { | 783 | switch (rma) { |
| 784 | case WORK_ACT_MISMATCH: | ||
| 785 | /* ignore this unmatched frame */ | ||
| 786 | break; | ||
| 764 | case WORK_ACT_NONE: | 787 | case WORK_ACT_NONE: |
| 765 | break; | 788 | break; |
| 766 | case WORK_ACT_DONE: | 789 | case WORK_ACT_DONE: |
