aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/work.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/work.c')
-rw-r--r--net/mac80211/work.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/net/mac80211/work.c b/net/mac80211/work.c
index 1e1ea3007b06..b0ba58589ca3 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
34enum work_action { 34enum 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,
@@ -574,7 +575,7 @@ ieee80211_rx_mgmt_auth(struct ieee80211_work *wk,
574 u16 auth_alg, auth_transaction, status_code; 575 u16 auth_alg, auth_transaction, status_code;
575 576
576 if (wk->type != IEEE80211_WORK_AUTH) 577 if (wk->type != IEEE80211_WORK_AUTH)
577 return WORK_ACT_NONE; 578 return WORK_ACT_MISMATCH;
578 579
579 if (len < 24 + 6) 580 if (len < 24 + 6)
580 return WORK_ACT_NONE; 581 return WORK_ACT_NONE;
@@ -625,6 +626,9 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_work *wk,
625 struct ieee802_11_elems elems; 626 struct ieee802_11_elems elems;
626 u8 *pos; 627 u8 *pos;
627 628
629 if (wk->type != IEEE80211_WORK_ASSOC)
630 return WORK_ACT_MISMATCH;
631
628 /* 632 /*
629 * AssocResp and ReassocResp have identical structure, so process both 633 * AssocResp and ReassocResp have identical structure, so process both
630 * of them in this function. 634 * of them in this function.
@@ -680,6 +684,12 @@ ieee80211_rx_mgmt_probe_resp(struct ieee80211_work *wk,
680 684
681 ASSERT_WORK_MTX(local); 685 ASSERT_WORK_MTX(local);
682 686
687 if (wk->type != IEEE80211_WORK_DIRECT_PROBE)
688 return WORK_ACT_MISMATCH;
689
690 if (len < 24 + 12)
691 return WORK_ACT_NONE;
692
683 baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; 693 baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
684 if (baselen > len) 694 if (baselen > len)
685 return WORK_ACT_NONE; 695 return WORK_ACT_NONE;
@@ -694,7 +704,7 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local,
694 struct ieee80211_rx_status *rx_status; 704 struct ieee80211_rx_status *rx_status;
695 struct ieee80211_mgmt *mgmt; 705 struct ieee80211_mgmt *mgmt;
696 struct ieee80211_work *wk; 706 struct ieee80211_work *wk;
697 enum work_action rma = WORK_ACT_NONE; 707 enum work_action rma;
698 u16 fc; 708 u16 fc;
699 709
700 rx_status = (struct ieee80211_rx_status *) skb->cb; 710 rx_status = (struct ieee80211_rx_status *) skb->cb;
@@ -741,7 +751,17 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local,
741 break; 751 break;
742 default: 752 default:
743 WARN_ON(1); 753 WARN_ON(1);
754 rma = WORK_ACT_NONE;
744 } 755 }
756
757 /*
758 * We've either received an unexpected frame, or we have
759 * multiple work items and need to match the frame to the
760 * right one.
761 */
762 if (rma == WORK_ACT_MISMATCH)
763 continue;
764
745 /* 765 /*
746 * We've processed this frame for that work, so it can't 766 * We've processed this frame for that work, so it can't
747 * belong to another work struct. 767 * belong to another work struct.
@@ -751,6 +771,9 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local,
751 } 771 }
752 772
753 switch (rma) { 773 switch (rma) {
774 case WORK_ACT_MISMATCH:
775 /* ignore this unmatched frame */
776 break;
754 case WORK_ACT_NONE: 777 case WORK_ACT_NONE:
755 break; 778 break;
756 case WORK_ACT_DONE: 779 case WORK_ACT_DONE: