mirror of
https://github.com/outbackdingo/mt76.git
synced 2026-10-24 05:16:57 +00:00
wifi: mt76: mt76x02: validate TX-status rate index before mac80211 handoff
mt76x02_mac_process_tx_rate() extracts the rate index straight from
the hardware's raw TX-status word with no bounds check for the
HT/HT_GF/VHT cases, and mt76x02_mac_fill_tx_status() ignores its
return value. A stale or corrupt hardware index reaches mac80211's
minstrel_ht rate control, whose per-group rate array is a fixed 10
entries (MCS_GROUP_RATES), causing an out-of-bounds write.
Validate the index in mt76x02_mac_process_tx_rate() (HT: 0-31,
VHT: MCS nibble 0-9) and have mt76x02_mac_fill_tx_status() bail out
cleanly on failure instead of passing an invalid index through.
Fixes: 7c1f88812690 ("mt76: unify send_tx_status and related helpers")
Cc: [email protected]
Tested-by: Devin Wittmayer <[email protected]>
Signed-off-by: Mark Anthony Agarro <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
committed by
Felix Fietkau
parent
4d82c99620
commit
0789c43c1a
+13
-6
@@ -302,10 +302,14 @@ mt76x02_mac_process_tx_rate(struct ieee80211_tx_rate *txrate, u16 rate,
|
|||||||
txrate->flags |= IEEE80211_TX_RC_GREEN_FIELD;
|
txrate->flags |= IEEE80211_TX_RC_GREEN_FIELD;
|
||||||
fallthrough;
|
fallthrough;
|
||||||
case MT_PHY_TYPE_HT:
|
case MT_PHY_TYPE_HT:
|
||||||
|
if (idx > 31)
|
||||||
|
return -EINVAL;
|
||||||
txrate->flags |= IEEE80211_TX_RC_MCS;
|
txrate->flags |= IEEE80211_TX_RC_MCS;
|
||||||
txrate->idx = idx;
|
txrate->idx = idx;
|
||||||
break;
|
break;
|
||||||
case MT_PHY_TYPE_VHT:
|
case MT_PHY_TYPE_VHT:
|
||||||
|
if ((idx & 0xf) > 9)
|
||||||
|
return -EINVAL;
|
||||||
txrate->flags |= IEEE80211_TX_RC_VHT_MCS;
|
txrate->flags |= IEEE80211_TX_RC_VHT_MCS;
|
||||||
txrate->idx = idx;
|
txrate->idx = idx;
|
||||||
break;
|
break;
|
||||||
@@ -493,18 +497,21 @@ mt76x02_mac_fill_tx_status(struct mt76x02_dev *dev, struct mt76x02_sta *msta,
|
|||||||
first_rate = st->rate & ~MT_PKTID_RATE;
|
first_rate = st->rate & ~MT_PKTID_RATE;
|
||||||
first_rate |= st->pktid & MT_PKTID_RATE;
|
first_rate |= st->pktid & MT_PKTID_RATE;
|
||||||
|
|
||||||
mt76x02_mac_process_tx_rate(&rate[0], first_rate,
|
if (mt76x02_mac_process_tx_rate(&rate[0], first_rate,
|
||||||
dev->mphy.chandef.chan->band);
|
dev->mphy.chandef.chan->band))
|
||||||
|
return;
|
||||||
} else if (rate[0].idx < 0) {
|
} else if (rate[0].idx < 0) {
|
||||||
if (!msta)
|
if (!msta)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mt76x02_mac_process_tx_rate(&rate[0], msta->wcid.tx_info,
|
if (mt76x02_mac_process_tx_rate(&rate[0], msta->wcid.tx_info,
|
||||||
dev->mphy.chandef.chan->band);
|
dev->mphy.chandef.chan->band))
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mt76x02_mac_process_tx_rate(&last_rate, st->rate,
|
if (mt76x02_mac_process_tx_rate(&last_rate, st->rate,
|
||||||
dev->mphy.chandef.chan->band);
|
dev->mphy.chandef.chan->band))
|
||||||
|
return;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(info->status.rates); i++) {
|
for (i = 0; i < ARRAY_SIZE(info->status.rates); i++) {
|
||||||
retry--;
|
retry--;
|
||||||
|
|||||||
Reference in New Issue
Block a user