Merge branch 'stable-3.2' into pandora-3.2
[pandora-kernel.git] / net / mac80211 / rx.c
index 6d0d37d..0cfb95a 100644 (file)
@@ -670,9 +670,10 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
 
  set_release_timer:
 
-               mod_timer(&tid_agg_rx->reorder_timer,
-                         tid_agg_rx->reorder_time[j] + 1 +
-                         HT_RX_REORDER_BUF_TIMEOUT);
+               if (!tid_agg_rx->removed)
+                       mod_timer(&tid_agg_rx->reorder_timer,
+                                 tid_agg_rx->reorder_time[j] + 1 +
+                                 HT_RX_REORDER_BUF_TIMEOUT);
        } else {
                del_timer(&tid_agg_rx->reorder_timer);
        }
@@ -1853,16 +1854,22 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
        if (!(status->rx_flags & IEEE80211_RX_AMSDU))
                return RX_CONTINUE;
 
-       if (ieee80211_has_a4(hdr->frame_control) &&
-           rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
-           !rx->sdata->u.vlan.sta)
-               return RX_DROP_UNUSABLE;
+       if (unlikely(ieee80211_has_a4(hdr->frame_control))) {
+               switch (rx->sdata->vif.type) {
+               case NL80211_IFTYPE_AP_VLAN:
+                       if (!rx->sdata->u.vlan.sta)
+                               return RX_DROP_UNUSABLE;
+                       break;
+               case NL80211_IFTYPE_STATION:
+                       if (!rx->sdata->u.mgd.use_4addr)
+                               return RX_DROP_UNUSABLE;
+                       break;
+               default:
+                       return RX_DROP_UNUSABLE;
+               }
+       }
 
-       if (is_multicast_ether_addr(hdr->addr1) &&
-           ((rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
-             rx->sdata->u.vlan.sta) ||
-            (rx->sdata->vif.type == NL80211_IFTYPE_STATION &&
-             rx->sdata->u.mgd.use_4addr)))
+       if (is_multicast_ether_addr(hdr->addr1))
                return RX_DROP_UNUSABLE;
 
        skb->dev = dev;
@@ -1952,7 +1959,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
                if (is_multicast_ether_addr(hdr->addr1)) {
                        mpp_addr = hdr->addr3;
                        proxied_addr = mesh_hdr->eaddr1;
-               } else if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6) {
+               } else if ((mesh_hdr->flags & MESH_FLAGS_AE) ==
+                           MESH_FLAGS_AE_A5_A6) {
                        /* has_a4 already checked in ieee80211_rx_mesh_check */
                        mpp_addr = hdr->addr4;
                        proxied_addr = mesh_hdr->eaddr2;
@@ -2835,6 +2843,30 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx,
                              sdata->vif.p2p))
                                return 0;
                        status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
+               } else {
+                       /*
+                        * 802.11-2016 Table 9-26 says that for data frames,
+                        * A1 must be the BSSID - we've checked that already
+                        * but may have accepted the wildcard
+                        * (ff:ff:ff:ff:ff:ff).
+                        *
+                        * It also says:
+                        *      The BSSID of the Data frame is determined as
+                        *      follows:
+                        *      a) If the STA is contained within an AP or is
+                        *         associated with an AP, the BSSID is the
+                        *         address currently in use by the STA
+                        *         contained in the AP.
+                        *
+                        * So we should not accept data frames with an address
+                        * that's multicast.
+                        *
+                        * Accepting it also opens a security problem because
+                        * stations could encrypt it with the GTK and inject
+                        * traffic that way.
+                        */
+                       if (ieee80211_is_data(hdr->frame_control) && multicast)
+                               return 0;
                }
                break;
        case NL80211_IFTYPE_WDS: