Skip to content

Commit dc66a12

Browse files
committed
wifi: mt76: add a wrapper for wcid access with validation
Several places use rcu_dereference to get a wcid entry without validating if the index exceeds the array boundary. Fix this by using a helper function, which handles validation. Link: https://patch.msgid.link/[email protected] Signed-off-by: Felix Fietkau <[email protected]>
1 parent 7035a08 commit dc66a12

File tree

17 files changed

+41
-68
lines changed

17 files changed

+41
-68
lines changed

drivers/net/wireless/mediatek/mt76/mt76.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1224,6 +1224,16 @@ static inline int mt76_wed_dma_setup(struct mt76_dev *dev, struct mt76_queue *q,
12241224
#define mt76_dereference(p, dev) \
12251225
rcu_dereference_protected(p, lockdep_is_held(&(dev)->mutex))
12261226

1227+
static inline struct mt76_wcid *
1228+
__mt76_wcid_ptr(struct mt76_dev *dev, u16 idx)
1229+
{
1230+
if (idx >= ARRAY_SIZE(dev->wcid))
1231+
return NULL;
1232+
return rcu_dereference(dev->wcid[idx]);
1233+
}
1234+
1235+
#define mt76_wcid_ptr(dev, idx) __mt76_wcid_ptr(&(dev)->mt76, idx)
1236+
12271237
struct mt76_dev *mt76_alloc_device(struct device *pdev, unsigned int size,
12281238
const struct ieee80211_ops *ops,
12291239
const struct mt76_driver_ops *drv_ops);

drivers/net/wireless/mediatek/mt76/mt7603/dma.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ mt7603_rx_loopback_skb(struct mt7603_dev *dev, struct sk_buff *skb)
4444
if (idx >= MT7603_WTBL_STA - 1)
4545
goto free;
4646

47-
wcid = rcu_dereference(dev->mt76.wcid[idx]);
47+
wcid = mt76_wcid_ptr(dev, idx);
4848
if (!wcid)
4949
goto free;
5050

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

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -487,10 +487,7 @@ mt7603_rx_get_wcid(struct mt7603_dev *dev, u8 idx, bool unicast)
487487
struct mt7603_sta *sta;
488488
struct mt76_wcid *wcid;
489489

490-
if (idx >= MT7603_WTBL_SIZE)
491-
return NULL;
492-
493-
wcid = rcu_dereference(dev->mt76.wcid[idx]);
490+
wcid = mt76_wcid_ptr(dev, idx);
494491
if (unicast || !wcid)
495492
return wcid;
496493

@@ -1266,12 +1263,9 @@ void mt7603_mac_add_txs(struct mt7603_dev *dev, void *data)
12661263
if (pid == MT_PACKET_ID_NO_ACK)
12671264
return;
12681265

1269-
if (wcidx >= MT7603_WTBL_SIZE)
1270-
return;
1271-
12721266
rcu_read_lock();
12731267

1274-
wcid = rcu_dereference(dev->mt76.wcid[wcidx]);
1268+
wcid = mt76_wcid_ptr(dev, wcidx);
12751269
if (!wcid)
12761270
goto out;
12771271

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

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,7 @@ static struct mt76_wcid *mt7615_rx_get_wcid(struct mt7615_dev *dev,
9090
struct mt7615_sta *sta;
9191
struct mt76_wcid *wcid;
9292

93-
if (idx >= MT7615_WTBL_SIZE)
94-
return NULL;
95-
96-
wcid = rcu_dereference(dev->mt76.wcid[idx]);
93+
wcid = mt76_wcid_ptr(dev, idx);
9794
if (unicast || !wcid)
9895
return wcid;
9996

@@ -1504,7 +1501,7 @@ static void mt7615_mac_add_txs(struct mt7615_dev *dev, void *data)
15041501

15051502
rcu_read_lock();
15061503

1507-
wcid = rcu_dereference(dev->mt76.wcid[wcidx]);
1504+
wcid = mt76_wcid_ptr(dev, wcidx);
15081505
if (!wcid)
15091506
goto out;
15101507

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1172,7 +1172,7 @@ void mt76_connac2_txwi_free(struct mt76_dev *dev, struct mt76_txwi_cache *t,
11721172
wcid_idx = wcid->idx;
11731173
} else {
11741174
wcid_idx = le32_get_bits(txwi[1], MT_TXD1_WLAN_IDX);
1175-
wcid = rcu_dereference(dev->wcid[wcid_idx]);
1175+
wcid = __mt76_wcid_ptr(dev, wcid_idx);
11761176

11771177
if (wcid && wcid->sta) {
11781178
sta = container_of((void *)wcid, struct ieee80211_sta,

drivers/net/wireless/mediatek/mt76/mt76x02.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -262,10 +262,7 @@ mt76x02_rx_get_sta(struct mt76_dev *dev, u8 idx)
262262
{
263263
struct mt76_wcid *wcid;
264264

265-
if (idx >= MT76x02_N_WCIDS)
266-
return NULL;
267-
268-
wcid = rcu_dereference(dev->wcid[idx]);
265+
wcid = __mt76_wcid_ptr(dev, idx);
269266
if (!wcid)
270267
return NULL;
271268

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -564,9 +564,7 @@ void mt76x02_send_tx_status(struct mt76x02_dev *dev,
564564

565565
rcu_read_lock();
566566

567-
if (stat->wcid < MT76x02_N_WCIDS)
568-
wcid = rcu_dereference(dev->mt76.wcid[stat->wcid]);
569-
567+
wcid = mt76_wcid_ptr(dev, stat->wcid);
570568
if (wcid && wcid->sta) {
571569
void *priv;
572570

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

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,7 @@ static struct mt76_wcid *mt7915_rx_get_wcid(struct mt7915_dev *dev,
5656
struct mt7915_sta *sta;
5757
struct mt76_wcid *wcid;
5858

59-
if (idx >= ARRAY_SIZE(dev->mt76.wcid))
60-
return NULL;
61-
62-
wcid = rcu_dereference(dev->mt76.wcid[idx]);
59+
wcid = mt76_wcid_ptr(dev, idx);
6360
if (unicast || !wcid)
6461
return wcid;
6562

@@ -917,7 +914,7 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
917914
u16 idx;
918915

919916
idx = FIELD_GET(MT_TX_FREE_WLAN_ID, info);
920-
wcid = rcu_dereference(dev->mt76.wcid[idx]);
917+
wcid = mt76_wcid_ptr(dev, idx);
921918
sta = wcid_to_sta(wcid);
922919
if (!sta)
923920
continue;
@@ -1013,12 +1010,9 @@ static void mt7915_mac_add_txs(struct mt7915_dev *dev, void *data)
10131010
if (pid < MT_PACKET_ID_WED)
10141011
return;
10151012

1016-
if (wcidx >= mt7915_wtbl_size(dev))
1017-
return;
1018-
10191013
rcu_read_lock();
10201014

1021-
wcid = rcu_dereference(dev->mt76.wcid[wcidx]);
1015+
wcid = mt76_wcid_ptr(dev, wcidx);
10221016
if (!wcid)
10231017
goto out;
10241018

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3986,7 +3986,7 @@ int mt7915_mcu_wed_wa_tx_stats(struct mt7915_dev *dev, u16 wlan_idx)
39863986

39873987
rcu_read_lock();
39883988

3989-
wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);
3989+
wcid = mt76_wcid_ptr(dev, wlan_idx);
39903990
if (wcid)
39913991
wcid->stats.tx_packets += le32_to_cpu(res->tx_packets);
39923992
else

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -587,12 +587,9 @@ static void mt7915_mmio_wed_update_rx_stats(struct mtk_wed_device *wed,
587587

588588
dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
589589

590-
if (idx >= mt7915_wtbl_size(dev))
591-
return;
592-
593590
rcu_read_lock();
594591

595-
wcid = rcu_dereference(dev->mt76.wcid[idx]);
592+
wcid = mt76_wcid_ptr(dev, idx);
596593
if (wcid) {
597594
wcid->stats.rx_bytes += le32_to_cpu(stats->rx_byte_cnt);
598595
wcid->stats.rx_packets += le32_to_cpu(stats->rx_pkt_cnt);

0 commit comments

Comments
 (0)