Skip to content

Commit 2a9e985

Browse files
LorenzoBianconiKalle Valo
authored andcommitted
mt76: fix possible pktid leak
Fix a possible idr pkt-id leak if the packet is dropped on tx side Fixes: bd1e3e7 ("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
1 parent ebb75b1 commit 2a9e985

File tree

5 files changed

+38
-27
lines changed

5 files changed

+38
-27
lines changed

drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,6 @@ int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
143143
if (!wcid)
144144
wcid = &dev->mt76.global_wcid;
145145

146-
pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
147-
148146
if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && msta) {
149147
struct mt7615_phy *phy = &dev->phy;
150148

@@ -164,6 +162,7 @@ int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
164162
if (id < 0)
165163
return id;
166164

165+
pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
167166
mt7615_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, sta,
168167
pid, key, false);
169168

drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,11 @@ EXPORT_SYMBOL_GPL(mt7663_usb_sdio_reg_map);
4343
static void
4444
mt7663_usb_sdio_write_txwi(struct mt7615_dev *dev, struct mt76_wcid *wcid,
4545
enum mt76_txq_id qid, struct ieee80211_sta *sta,
46-
struct sk_buff *skb)
46+
int pid, struct sk_buff *skb)
4747
{
4848
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
4949
struct ieee80211_key_conf *key = info->control.hw_key;
5050
__le32 *txwi;
51-
int pid;
52-
53-
if (!wcid)
54-
wcid = &dev->mt76.global_wcid;
55-
56-
pid = mt76_tx_status_skb_add(&dev->mt76, wcid, skb);
5751

5852
txwi = (__le32 *)(skb->data - MT_USB_TXD_SIZE);
5953
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,
195189
struct sk_buff *skb = tx_info->skb;
196190
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
197191
struct mt7615_sta *msta;
198-
int pad;
192+
int pad, err, pktid;
199193

200194
msta = wcid ? container_of(wcid, struct mt7615_sta, wcid) : NULL;
195+
if (!wcid)
196+
wcid = &dev->mt76.global_wcid;
197+
201198
if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) &&
202199
msta && !msta->rate_probe) {
203200
/* request to configure sampling rate */
@@ -207,7 +204,8 @@ int mt7663_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
207204
spin_unlock_bh(&dev->mt76.lock);
208205
}
209206

210-
mt7663_usb_sdio_write_txwi(dev, wcid, qid, sta, skb);
207+
pktid = mt76_tx_status_skb_add(&dev->mt76, wcid, skb);
208+
mt7663_usb_sdio_write_txwi(dev, wcid, qid, sta, pktid, skb);
211209
if (mt76_is_usb(mdev)) {
212210
u32 len = skb->len;
213211

@@ -217,7 +215,12 @@ int mt7663_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
217215
pad = round_up(skb->len, 4) - skb->len;
218216
}
219217

220-
return mt76_skb_adjust_pad(skb, pad);
218+
err = mt76_skb_adjust_pad(skb, pad);
219+
if (err)
220+
/* Release pktid in case of error. */
221+
idr_remove(&wcid->pktid, pktid);
222+
223+
return err;
221224
}
222225
EXPORT_SYMBOL_GPL(mt7663_usb_sdio_tx_prepare_skb);
223226

drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
7272
bool ampdu = IEEE80211_SKB_CB(tx_info->skb)->flags & IEEE80211_TX_CTL_AMPDU;
7373
enum mt76_qsel qsel;
7474
u32 flags;
75+
int err;
7576

7677
mt76_insert_hdr_pad(tx_info->skb);
7778

@@ -106,7 +107,12 @@ int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
106107
ewma_pktlen_add(&msta->pktlen, tx_info->skb->len);
107108
}
108109

109-
return mt76x02u_skb_dma_info(tx_info->skb, WLAN_PORT, flags);
110+
err = mt76x02u_skb_dma_info(tx_info->skb, WLAN_PORT, flags);
111+
if (err && wcid)
112+
/* Release pktid in case of error. */
113+
idr_remove(&wcid->pktid, pid);
114+
115+
return err;
110116
}
111117
EXPORT_SYMBOL_GPL(mt76x02u_tx_prepare_skb);
112118

drivers/net/wireless/mediatek/mt76/mt7915/mac.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,8 +1151,14 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
11511151
}
11521152
}
11531153

1154-
pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
1154+
t = (struct mt76_txwi_cache *)(txwi + mdev->drv->txwi_size);
1155+
t->skb = tx_info->skb;
1156+
1157+
id = mt76_token_consume(mdev, &t);
1158+
if (id < 0)
1159+
return id;
11551160

1161+
pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
11561162
mt7915_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, pid, key,
11571163
false);
11581164

@@ -1178,13 +1184,6 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
11781184
txp->bss_idx = mvif->idx;
11791185
}
11801186

1181-
t = (struct mt76_txwi_cache *)(txwi + mdev->drv->txwi_size);
1182-
t->skb = tx_info->skb;
1183-
1184-
id = mt76_token_consume(mdev, &t);
1185-
if (id < 0)
1186-
return id;
1187-
11881187
txp->token = cpu_to_le16(id);
11891188
if (test_bit(MT_WCID_FLAG_4ADDR, &wcid->flags))
11901189
txp->rept_wds_wcid = cpu_to_le16(wcid->idx);

drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,14 +142,12 @@ int mt7921s_mac_reset(struct mt7921_dev *dev)
142142
static void
143143
mt7921s_write_txwi(struct mt7921_dev *dev, struct mt76_wcid *wcid,
144144
enum mt76_txq_id qid, struct ieee80211_sta *sta,
145-
struct sk_buff *skb)
145+
int pid, struct sk_buff *skb)
146146
{
147147
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
148148
struct ieee80211_key_conf *key = info->control.hw_key;
149149
__le32 *txwi;
150-
int pid;
151150

152-
pid = mt76_tx_status_skb_add(&dev->mt76, wcid, skb);
153151
txwi = (__le32 *)(skb->data - MT_SDIO_TXD_SIZE);
154152
memset(txwi, 0, MT_SDIO_TXD_SIZE);
155153
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,
164162
struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
165163
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_info->skb);
166164
struct sk_buff *skb = tx_info->skb;
167-
int pad;
165+
int err, pad, pktid;
168166

169167
if (unlikely(tx_info->skb->len <= ETH_HLEN))
170168
return -EINVAL;
@@ -181,12 +179,18 @@ int mt7921s_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
181179
}
182180
}
183181

184-
mt7921s_write_txwi(dev, wcid, qid, sta, skb);
182+
pktid = mt76_tx_status_skb_add(&dev->mt76, wcid, skb);
183+
mt7921s_write_txwi(dev, wcid, qid, sta, pktid, skb);
185184

186185
mt7921_skb_add_sdio_hdr(skb, MT7921_SDIO_DATA);
187186
pad = round_up(skb->len, 4) - skb->len;
188187

189-
return mt76_skb_adjust_pad(skb, pad);
188+
err = mt76_skb_adjust_pad(skb, pad);
189+
if (err)
190+
/* Release pktid in case of error. */
191+
idr_remove(&wcid->pktid, pktid);
192+
193+
return err;
190194
}
191195

192196
void mt7921s_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e)

0 commit comments

Comments
 (0)