mt7601u: watch out for invalid-length frames
Users of older Ralink devices report that received frames sometimes have zero length. Watch out for that. Signed-off-by: Jakub Kicinski <kubakici@wp.pl> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
parent
69647fab13
commit
2af6d21fce
@ -37,16 +37,20 @@ mt7601u_rx_skb_from_seg(struct mt7601u_dev *dev, struct mt7601u_rxwi *rxwi,
|
|||||||
void *data, u32 seg_len, u32 truesize, struct page *p)
|
void *data, u32 seg_len, u32 truesize, struct page *p)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
u32 true_len;
|
u32 true_len, hdr_len = 0, copy, frag;
|
||||||
int hdr_len, copy, frag;
|
|
||||||
|
|
||||||
skb = alloc_skb(p ? 128 : seg_len, GFP_ATOMIC);
|
skb = alloc_skb(p ? 128 : seg_len, GFP_ATOMIC);
|
||||||
if (!skb)
|
if (!skb)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
true_len = mt76_mac_process_rx(dev, skb, data, rxwi);
|
true_len = mt76_mac_process_rx(dev, skb, data, rxwi);
|
||||||
|
if (!true_len || true_len > seg_len)
|
||||||
|
goto bad_frame;
|
||||||
|
|
||||||
hdr_len = ieee80211_get_hdrlen_from_buf(data, true_len);
|
hdr_len = ieee80211_get_hdrlen_from_buf(data, true_len);
|
||||||
|
if (!hdr_len)
|
||||||
|
goto bad_frame;
|
||||||
|
|
||||||
if (rxwi->rxinfo & cpu_to_le32(MT_RXINFO_L2PAD)) {
|
if (rxwi->rxinfo & cpu_to_le32(MT_RXINFO_L2PAD)) {
|
||||||
memcpy(skb_put(skb, hdr_len), data, hdr_len);
|
memcpy(skb_put(skb, hdr_len), data, hdr_len);
|
||||||
|
|
||||||
@ -69,6 +73,12 @@ mt7601u_rx_skb_from_seg(struct mt7601u_dev *dev, struct mt7601u_rxwi *rxwi,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return skb;
|
return skb;
|
||||||
|
|
||||||
|
bad_frame:
|
||||||
|
dev_err_ratelimited(dev->dev, "Error: incorrect frame len:%u hdr:%u\n",
|
||||||
|
true_len, hdr_len);
|
||||||
|
dev_kfree_skb(skb);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mt7601u_rx_process_seg(struct mt7601u_dev *dev, u8 *data,
|
static void mt7601u_rx_process_seg(struct mt7601u_dev *dev, u8 *data,
|
||||||
|
@ -450,10 +450,14 @@ u32 mt76_mac_process_rx(struct mt7601u_dev *dev, struct sk_buff *skb,
|
|||||||
{
|
{
|
||||||
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
|
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
|
||||||
struct mt7601u_rxwi *rxwi = rxi;
|
struct mt7601u_rxwi *rxwi = rxi;
|
||||||
u32 ctl = le32_to_cpu(rxwi->ctl);
|
u32 len, ctl = le32_to_cpu(rxwi->ctl);
|
||||||
u16 rate = le16_to_cpu(rxwi->rate);
|
u16 rate = le16_to_cpu(rxwi->rate);
|
||||||
int rssi;
|
int rssi;
|
||||||
|
|
||||||
|
len = MT76_GET(MT_RXWI_CTL_MPDU_LEN, ctl);
|
||||||
|
if (len < 10)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (rxwi->rxinfo & cpu_to_le32(MT_RXINFO_DECRYPT)) {
|
if (rxwi->rxinfo & cpu_to_le32(MT_RXINFO_DECRYPT)) {
|
||||||
status->flag |= RX_FLAG_DECRYPTED;
|
status->flag |= RX_FLAG_DECRYPTED;
|
||||||
status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;
|
status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;
|
||||||
@ -474,7 +478,7 @@ u32 mt76_mac_process_rx(struct mt7601u_dev *dev, struct sk_buff *skb,
|
|||||||
dev->avg_rssi = (dev->avg_rssi * 15) / 16 + (rssi << 8);
|
dev->avg_rssi = (dev->avg_rssi * 15) / 16 + (rssi << 8);
|
||||||
spin_unlock_bh(&dev->con_mon_lock);
|
spin_unlock_bh(&dev->con_mon_lock);
|
||||||
|
|
||||||
return MT76_GET(MT_RXWI_CTL_MPDU_LEN, ctl);
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum mt76_cipher_type
|
static enum mt76_cipher_type
|
||||||
|
Loading…
Reference in New Issue
Block a user