]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
mt76: do not pass the received frame with decryption error
authorXing Song <xing.song@mediatek.com>
Fri, 19 Nov 2021 06:37:06 +0000 (14:37 +0800)
committerPaolo Pisati <paolo.pisati@canonical.com>
Fri, 28 Jan 2022 10:02:45 +0000 (11:02 +0100)
BugLink: https://bugs.launchpad.net/bugs/1959376
[ Upstream commit dd28dea52ad9376d2b243a8981726646e1f60b1a ]

MAC80211 doesn't care any decryption error in 802.3 path, so received
frame will be dropped if HW tell us that the cipher configuration is not
matched as well as the header has been translated to 802.3. This case only
appears when IEEE80211_FCTL_PROTECTED is 0 and cipher suit is not none in
the corresponding HW entry.

The received frame is only reported to monitor interface if HW decryption
block tell us there is ICV error or CCMP/BIP/WPI MIC error. Note in this
case the reported frame is decrypted 802.11 frame and the payload may be
malformed due to mismatched key.

Signed-off-by: Xing Song <xing.song@mediatek.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
drivers/net/wireless/mediatek/mt76/mt7603/mac.c
drivers/net/wireless/mediatek/mt76/mt7615/mac.c
drivers/net/wireless/mediatek/mt76/mt7915/mac.c
drivers/net/wireless/mediatek/mt76/mt7921/mac.c

index 3972c56136a200b39f9c00ffcb7fd0708c97dca7..65f1f2bb808353f925703ca76f991f74cfc53398 100644 (file)
@@ -525,6 +525,10 @@ mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb)
        if (rxd2 & MT_RXD2_NORMAL_TKIP_MIC_ERR)
                status->flag |= RX_FLAG_MMIC_ERROR;
 
+       /* ICV error or CCMP/BIP/WPI MIC error */
+       if (rxd2 & MT_RXD2_NORMAL_ICV_ERR)
+               status->flag |= RX_FLAG_ONLY_MONITOR;
+
        if (FIELD_GET(MT_RXD2_NORMAL_SEC_MODE, rxd2) != 0 &&
            !(rxd2 & (MT_RXD2_NORMAL_CLM | MT_RXD2_NORMAL_CM))) {
                status->flag |= RX_FLAG_DECRYPTED;
index 5455231f51881a529a8e9e040b60b2896a3436ea..f2704149834a0ef9e21934372bcfdafd0ae0e183 100644 (file)
@@ -286,9 +286,16 @@ static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb)
        if (rxd2 & MT_RXD2_NORMAL_AMSDU_ERR)
                return -EINVAL;
 
+       hdr_trans = rxd1 & MT_RXD1_NORMAL_HDR_TRANS;
+       if (hdr_trans && (rxd2 & MT_RXD2_NORMAL_CM))
+               return -EINVAL;
+
+       /* ICV error or CCMP/BIP/WPI MIC error */
+       if (rxd2 & MT_RXD2_NORMAL_ICV_ERR)
+               status->flag |= RX_FLAG_ONLY_MONITOR;
+
        unicast = (rxd1 & MT_RXD1_NORMAL_ADDR_TYPE) == MT_RXD1_NORMAL_U2M;
        idx = FIELD_GET(MT_RXD2_NORMAL_WLAN_IDX, rxd2);
-       hdr_trans = rxd1 & MT_RXD1_NORMAL_HDR_TRANS;
        status->wcid = mt7615_rx_get_wcid(dev, idx, unicast);
 
        if (status->wcid) {
index bbc996f86b5c33dc57197aa568afe6e8ed0402e2..ff613d7056119f73ed0634612d632d2c01728acf 100644 (file)
@@ -349,9 +349,16 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
        if (rxd2 & MT_RXD2_NORMAL_AMSDU_ERR)
                return -EINVAL;
 
+       hdr_trans = rxd2 & MT_RXD2_NORMAL_HDR_TRANS;
+       if (hdr_trans && (rxd1 & MT_RXD1_NORMAL_CM))
+               return -EINVAL;
+
+       /* ICV error or CCMP/BIP/WPI MIC error */
+       if (rxd1 & MT_RXD1_NORMAL_ICV_ERR)
+               status->flag |= RX_FLAG_ONLY_MONITOR;
+
        unicast = FIELD_GET(MT_RXD3_NORMAL_ADDR_TYPE, rxd3) == MT_RXD3_NORMAL_U2M;
        idx = FIELD_GET(MT_RXD1_NORMAL_WLAN_IDX, rxd1);
-       hdr_trans = rxd2 & MT_RXD2_NORMAL_HDR_TRANS;
        status->wcid = mt7915_rx_get_wcid(dev, idx, unicast);
 
        if (status->wcid) {
index 8a16f3f4d52533ca0b1e35aee88b62dc797ff5d6..04a288029c98eb29d4280ed974de26dbb43b73a7 100644 (file)
@@ -383,10 +383,17 @@ int mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
        if (rxd2 & MT_RXD2_NORMAL_AMSDU_ERR)
                return -EINVAL;
 
+       hdr_trans = rxd2 & MT_RXD2_NORMAL_HDR_TRANS;
+       if (hdr_trans && (rxd1 & MT_RXD1_NORMAL_CM))
+               return -EINVAL;
+
+       /* ICV error or CCMP/BIP/WPI MIC error */
+       if (rxd1 & MT_RXD1_NORMAL_ICV_ERR)
+               status->flag |= RX_FLAG_ONLY_MONITOR;
+
        chfreq = FIELD_GET(MT_RXD3_NORMAL_CH_FREQ, rxd3);
        unicast = FIELD_GET(MT_RXD3_NORMAL_ADDR_TYPE, rxd3) == MT_RXD3_NORMAL_U2M;
        idx = FIELD_GET(MT_RXD1_NORMAL_WLAN_IDX, rxd1);
-       hdr_trans = rxd2 & MT_RXD2_NORMAL_HDR_TRANS;
        status->wcid = mt7921_rx_get_wcid(dev, idx, unicast);
 
        if (status->wcid) {