wifi: mac80211: drop some unprotected action frames
[linux-2.6-microblaze.git] / net / mac80211 / rx.c
index e35d6ba..e579581 100644 (file)
@@ -2405,9 +2405,9 @@ static int ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc)
 
 static int ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx)
 {
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
        struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
-       __le16 fc = hdr->frame_control;
+       struct ieee80211_mgmt *mgmt = (void *)rx->skb->data;
+       __le16 fc = mgmt->frame_control;
 
        /*
         * Pass through unencrypted frames if the hardware has
@@ -2416,6 +2416,11 @@ static int ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx)
        if (status->flag & RX_FLAG_DECRYPTED)
                return 0;
 
+       /* drop unicast protected dual (that wasn't protected) */
+       if (ieee80211_is_action(fc) &&
+           mgmt->u.action.category == WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION)
+               return -EACCES;
+
        if (rx->sta && test_sta_flag(rx->sta, WLAN_STA_MFP)) {
                if (unlikely(!ieee80211_has_protected(fc) &&
                             ieee80211_is_unicast_robust_mgmt_frame(rx->skb))) {
@@ -2458,6 +2463,12 @@ static int ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx)
                if (unlikely(ieee80211_is_action(fc) && !rx->key &&
                             ieee80211_is_robust_mgmt_frame(rx->skb)))
                        return -EACCES;
+
+               /* drop unicast public action frames when using MPF */
+               if (is_unicast_ether_addr(mgmt->da) &&
+                   ieee80211_is_public_action((void *)rx->skb->data,
+                                              rx->skb->len))
+                       return -EACCES;
        }
 
        return 0;