mirror of
https://github.com/outbackdingo/mt76.git
synced 2026-10-24 13:26:48 +00:00
wifi: mt76: mt7615: fix NULL deref in mt7615_mac_set_rates
mt7615_tx() falls back to the vif BSS wcid when mac80211 hands a frame over without a station, e.g. while a station is being torn down, and to the global wcid when there is no vif either. Both tx_prepare_skb implementations derive a mt7615_sta from that wcid unconditionally and, if the rate control probe flag is set, pass it to mt7615_mac_set_rates(), which dereferences the NULL vif backpointer of the per-vif embedded sta: Unable to handle kernel read from unreadable memory at virtual address 0000000000000002 ... pc : mt7615_mac_set_rates lr : mt7615_tx_prepare_skb Neither entry is rate controlled by mac80211: the embedded sta has an empty rate set, and for the global wcid the container_of does not yield a valid mt7615_sta at all. Only resolve the sta for wcids that belong to a station. Reported-by: Chad Monroe <[email protected]> Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
+3
-2
@@ -68,10 +68,11 @@ int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
|
|||||||
int pid, id;
|
int pid, id;
|
||||||
u8 *txwi = (u8 *)txwi_ptr;
|
u8 *txwi = (u8 *)txwi_ptr;
|
||||||
struct mt76_txwi_cache *t;
|
struct mt76_txwi_cache *t;
|
||||||
struct mt7615_sta *msta;
|
struct mt7615_sta *msta = NULL;
|
||||||
void *txp;
|
void *txp;
|
||||||
|
|
||||||
msta = wcid ? container_of(wcid, struct mt7615_sta, wcid) : NULL;
|
if (wcid && wcid->sta)
|
||||||
|
msta = container_of(wcid, struct mt7615_sta, wcid);
|
||||||
if (!wcid)
|
if (!wcid)
|
||||||
wcid = &dev->mt76.global_wcid;
|
wcid = &dev->mt76.global_wcid;
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -187,10 +187,11 @@ 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 ieee80211_key_conf *key = info->control.hw_key;
|
struct ieee80211_key_conf *key = info->control.hw_key;
|
||||||
struct mt7615_sta *msta;
|
struct mt7615_sta *msta = NULL;
|
||||||
int pad, err, pktid;
|
int pad, err, pktid;
|
||||||
|
|
||||||
msta = wcid ? container_of(wcid, struct mt7615_sta, wcid) : NULL;
|
if (wcid && wcid->sta)
|
||||||
|
msta = container_of(wcid, struct mt7615_sta, wcid);
|
||||||
if (!wcid)
|
if (!wcid)
|
||||||
wcid = &dev->mt76.global_wcid;
|
wcid = &dev->mt76.global_wcid;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user