mt76: fix possible pktid leak
Fix a possible idr pkt-id leak if the packet is dropped on tx side Fixes: bd1e3e7b693c ("mt76: introduce packet_id idr") Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> Acked-by: Felix Fietkau <nbd@nbd.name> Signed-off-by: Kalle Valo <kvalo@codeaurora.org> Link: https://lore.kernel.org/r/a560caffcc24452fb48af53904bbe5c45ea5db93.1637602268.git.lorenzo@kernel.org
This commit is contained in:
parent
ebb75b1b43
commit
2a9e985747
@ -143,8 +143,6 @@ int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
|
|||||||
if (!wcid)
|
if (!wcid)
|
||||||
wcid = &dev->mt76.global_wcid;
|
wcid = &dev->mt76.global_wcid;
|
||||||
|
|
||||||
pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
|
|
||||||
|
|
||||||
if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && msta) {
|
if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && msta) {
|
||||||
struct mt7615_phy *phy = &dev->phy;
|
struct mt7615_phy *phy = &dev->phy;
|
||||||
|
|
||||||
@ -164,6 +162,7 @@ int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
|
|||||||
if (id < 0)
|
if (id < 0)
|
||||||
return id;
|
return id;
|
||||||
|
|
||||||
|
pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
|
||||||
mt7615_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, sta,
|
mt7615_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, sta,
|
||||||
pid, key, false);
|
pid, key, false);
|
||||||
|
|
||||||
|
@ -43,17 +43,11 @@ EXPORT_SYMBOL_GPL(mt7663_usb_sdio_reg_map);
|
|||||||
static void
|
static void
|
||||||
mt7663_usb_sdio_write_txwi(struct mt7615_dev *dev, struct mt76_wcid *wcid,
|
mt7663_usb_sdio_write_txwi(struct mt7615_dev *dev, struct mt76_wcid *wcid,
|
||||||
enum mt76_txq_id qid, struct ieee80211_sta *sta,
|
enum mt76_txq_id qid, struct ieee80211_sta *sta,
|
||||||
struct sk_buff *skb)
|
int pid, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||||
struct ieee80211_key_conf *key = info->control.hw_key;
|
struct ieee80211_key_conf *key = info->control.hw_key;
|
||||||
__le32 *txwi;
|
__le32 *txwi;
|
||||||
int pid;
|
|
||||||
|
|
||||||
if (!wcid)
|
|
||||||
wcid = &dev->mt76.global_wcid;
|
|
||||||
|
|
||||||
pid = mt76_tx_status_skb_add(&dev->mt76, wcid, skb);
|
|
||||||
|
|
||||||
txwi = (__le32 *)(skb->data - MT_USB_TXD_SIZE);
|
txwi = (__le32 *)(skb->data - MT_USB_TXD_SIZE);
|
||||||
memset(txwi, 0, MT_USB_TXD_SIZE);
|
memset(txwi, 0, MT_USB_TXD_SIZE);
|
||||||
@ -195,9 +189,12 @@ int mt7663_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
|
|||||||
struct sk_buff *skb = tx_info->skb;
|
struct sk_buff *skb = tx_info->skb;
|
||||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||||
struct mt7615_sta *msta;
|
struct mt7615_sta *msta;
|
||||||
int pad;
|
int pad, err, pktid;
|
||||||
|
|
||||||
msta = wcid ? container_of(wcid, struct mt7615_sta, wcid) : NULL;
|
msta = wcid ? container_of(wcid, struct mt7615_sta, wcid) : NULL;
|
||||||
|
if (!wcid)
|
||||||
|
wcid = &dev->mt76.global_wcid;
|
||||||
|
|
||||||
if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) &&
|
if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) &&
|
||||||
msta && !msta->rate_probe) {
|
msta && !msta->rate_probe) {
|
||||||
/* request to configure sampling rate */
|
/* request to configure sampling rate */
|
||||||
@ -207,7 +204,8 @@ int mt7663_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
|
|||||||
spin_unlock_bh(&dev->mt76.lock);
|
spin_unlock_bh(&dev->mt76.lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
mt7663_usb_sdio_write_txwi(dev, wcid, qid, sta, skb);
|
pktid = mt76_tx_status_skb_add(&dev->mt76, wcid, skb);
|
||||||
|
mt7663_usb_sdio_write_txwi(dev, wcid, qid, sta, pktid, skb);
|
||||||
if (mt76_is_usb(mdev)) {
|
if (mt76_is_usb(mdev)) {
|
||||||
u32 len = skb->len;
|
u32 len = skb->len;
|
||||||
|
|
||||||
@ -217,7 +215,12 @@ int mt7663_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
|
|||||||
pad = round_up(skb->len, 4) - skb->len;
|
pad = round_up(skb->len, 4) - skb->len;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mt76_skb_adjust_pad(skb, pad);
|
err = mt76_skb_adjust_pad(skb, pad);
|
||||||
|
if (err)
|
||||||
|
/* Release pktid in case of error. */
|
||||||
|
idr_remove(&wcid->pktid, pktid);
|
||||||
|
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(mt7663_usb_sdio_tx_prepare_skb);
|
EXPORT_SYMBOL_GPL(mt7663_usb_sdio_tx_prepare_skb);
|
||||||
|
|
||||||
|
@ -72,6 +72,7 @@ int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
|
|||||||
bool ampdu = IEEE80211_SKB_CB(tx_info->skb)->flags & IEEE80211_TX_CTL_AMPDU;
|
bool ampdu = IEEE80211_SKB_CB(tx_info->skb)->flags & IEEE80211_TX_CTL_AMPDU;
|
||||||
enum mt76_qsel qsel;
|
enum mt76_qsel qsel;
|
||||||
u32 flags;
|
u32 flags;
|
||||||
|
int err;
|
||||||
|
|
||||||
mt76_insert_hdr_pad(tx_info->skb);
|
mt76_insert_hdr_pad(tx_info->skb);
|
||||||
|
|
||||||
@ -106,7 +107,12 @@ int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
|
|||||||
ewma_pktlen_add(&msta->pktlen, tx_info->skb->len);
|
ewma_pktlen_add(&msta->pktlen, tx_info->skb->len);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mt76x02u_skb_dma_info(tx_info->skb, WLAN_PORT, flags);
|
err = mt76x02u_skb_dma_info(tx_info->skb, WLAN_PORT, flags);
|
||||||
|
if (err && wcid)
|
||||||
|
/* Release pktid in case of error. */
|
||||||
|
idr_remove(&wcid->pktid, pid);
|
||||||
|
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(mt76x02u_tx_prepare_skb);
|
EXPORT_SYMBOL_GPL(mt76x02u_tx_prepare_skb);
|
||||||
|
|
||||||
|
@ -1151,8 +1151,14 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
|
t = (struct mt76_txwi_cache *)(txwi + mdev->drv->txwi_size);
|
||||||
|
t->skb = tx_info->skb;
|
||||||
|
|
||||||
|
id = mt76_token_consume(mdev, &t);
|
||||||
|
if (id < 0)
|
||||||
|
return id;
|
||||||
|
|
||||||
|
pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
|
||||||
mt7915_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, pid, key,
|
mt7915_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, pid, key,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
@ -1178,13 +1184,6 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
|
|||||||
txp->bss_idx = mvif->idx;
|
txp->bss_idx = mvif->idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
t = (struct mt76_txwi_cache *)(txwi + mdev->drv->txwi_size);
|
|
||||||
t->skb = tx_info->skb;
|
|
||||||
|
|
||||||
id = mt76_token_consume(mdev, &t);
|
|
||||||
if (id < 0)
|
|
||||||
return id;
|
|
||||||
|
|
||||||
txp->token = cpu_to_le16(id);
|
txp->token = cpu_to_le16(id);
|
||||||
if (test_bit(MT_WCID_FLAG_4ADDR, &wcid->flags))
|
if (test_bit(MT_WCID_FLAG_4ADDR, &wcid->flags))
|
||||||
txp->rept_wds_wcid = cpu_to_le16(wcid->idx);
|
txp->rept_wds_wcid = cpu_to_le16(wcid->idx);
|
||||||
|
@ -142,14 +142,12 @@ out:
|
|||||||
static void
|
static void
|
||||||
mt7921s_write_txwi(struct mt7921_dev *dev, struct mt76_wcid *wcid,
|
mt7921s_write_txwi(struct mt7921_dev *dev, struct mt76_wcid *wcid,
|
||||||
enum mt76_txq_id qid, struct ieee80211_sta *sta,
|
enum mt76_txq_id qid, struct ieee80211_sta *sta,
|
||||||
struct sk_buff *skb)
|
int pid, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||||
struct ieee80211_key_conf *key = info->control.hw_key;
|
struct ieee80211_key_conf *key = info->control.hw_key;
|
||||||
__le32 *txwi;
|
__le32 *txwi;
|
||||||
int pid;
|
|
||||||
|
|
||||||
pid = mt76_tx_status_skb_add(&dev->mt76, wcid, skb);
|
|
||||||
txwi = (__le32 *)(skb->data - MT_SDIO_TXD_SIZE);
|
txwi = (__le32 *)(skb->data - MT_SDIO_TXD_SIZE);
|
||||||
memset(txwi, 0, MT_SDIO_TXD_SIZE);
|
memset(txwi, 0, MT_SDIO_TXD_SIZE);
|
||||||
mt7921_mac_write_txwi(dev, txwi, skb, wcid, key, pid, false);
|
mt7921_mac_write_txwi(dev, txwi, skb, wcid, key, pid, false);
|
||||||
@ -164,7 +162,7 @@ int mt7921s_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
|
|||||||
struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
|
struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
|
||||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_info->skb);
|
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_info->skb);
|
||||||
struct sk_buff *skb = tx_info->skb;
|
struct sk_buff *skb = tx_info->skb;
|
||||||
int pad;
|
int err, pad, pktid;
|
||||||
|
|
||||||
if (unlikely(tx_info->skb->len <= ETH_HLEN))
|
if (unlikely(tx_info->skb->len <= ETH_HLEN))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -181,12 +179,18 @@ int mt7921s_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mt7921s_write_txwi(dev, wcid, qid, sta, skb);
|
pktid = mt76_tx_status_skb_add(&dev->mt76, wcid, skb);
|
||||||
|
mt7921s_write_txwi(dev, wcid, qid, sta, pktid, skb);
|
||||||
|
|
||||||
mt7921_skb_add_sdio_hdr(skb, MT7921_SDIO_DATA);
|
mt7921_skb_add_sdio_hdr(skb, MT7921_SDIO_DATA);
|
||||||
pad = round_up(skb->len, 4) - skb->len;
|
pad = round_up(skb->len, 4) - skb->len;
|
||||||
|
|
||||||
return mt76_skb_adjust_pad(skb, pad);
|
err = mt76_skb_adjust_pad(skb, pad);
|
||||||
|
if (err)
|
||||||
|
/* Release pktid in case of error. */
|
||||||
|
idr_remove(&wcid->pktid, pktid);
|
||||||
|
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mt7921s_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e)
|
void mt7921s_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user