mt76: allow receiving frames with invalid CCMP PN via monitor interfaces
authorFelix Fietkau <nbd@nbd.name>
Thu, 23 Jun 2022 12:21:18 +0000 (14:21 +0200)
committerFelix Fietkau <nbd@nbd.name>
Mon, 11 Jul 2022 11:40:03 +0000 (13:40 +0200)
This can be useful for debugging

Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mac80211.c

index ecf5bd9..cb41f54 100644 (file)
@@ -1018,7 +1018,7 @@ mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb,
        *hw = mt76_phy_hw(dev, mstat.ext_phy);
 }
 
-static int
+static void
 mt76_check_ccmp_pn(struct sk_buff *skb)
 {
        struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
@@ -1028,13 +1028,13 @@ mt76_check_ccmp_pn(struct sk_buff *skb)
        int ret;
 
        if (!(status->flag & RX_FLAG_DECRYPTED))
-               return 0;
+               return;
 
        if (status->flag & RX_FLAG_ONLY_MONITOR)
-               return 0;
+               return;
 
        if (!wcid || !wcid->rx_check_pn)
-               return 0;
+               return;
 
        security_idx = status->qos_ctl & IEEE80211_QOS_CTL_TID_MASK;
        if (status->flag & RX_FLAG_8023)
@@ -1048,7 +1048,7 @@ mt76_check_ccmp_pn(struct sk_buff *skb)
                 */
                if (ieee80211_is_frag(hdr) &&
                    !ieee80211_is_first_frag(hdr->frame_control))
-                       return 0;
+                       return;
        }
 
        /* IEEE 802.11-2020, 12.5.3.4.4 "PN and replay detection" c):
@@ -1065,15 +1065,15 @@ skip_hdr_check:
        BUILD_BUG_ON(sizeof(status->iv) != sizeof(wcid->rx_key_pn[0]));
        ret = memcmp(status->iv, wcid->rx_key_pn[security_idx],
                     sizeof(status->iv));
-       if (ret <= 0)
-               return -EINVAL; /* replay */
+       if (ret <= 0) {
+               status->flag |= RX_FLAG_ONLY_MONITOR;
+               return;
+       }
 
        memcpy(wcid->rx_key_pn[security_idx], status->iv, sizeof(status->iv));
 
        if (status->flag & RX_FLAG_IV_STRIPPED)
                status->flag |= RX_FLAG_PN_VALIDATED;
-
-       return 0;
 }
 
 static void
@@ -1246,11 +1246,7 @@ void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
        while ((skb = __skb_dequeue(frames)) != NULL) {
                struct sk_buff *nskb = skb_shinfo(skb)->frag_list;
 
-               if (mt76_check_ccmp_pn(skb)) {
-                       dev_kfree_skb(skb);
-                       continue;
-               }
-
+               mt76_check_ccmp_pn(skb);
                skb_shinfo(skb)->frag_list = NULL;
                mt76_rx_convert(dev, skb, &hw, &sta);
                ieee80211_rx_list(hw, sta, skb, &list);