LinuxKPI: 802.11: catch possible NULL pointer deref with mt76
With mt76 we, for the first time, see that txstat->skb or txstat->info may not be filled in linuxkpi_ieee80211_tx_status_ext(). Guard for these cases checking for skb and info to be not NULL and assume a TX failure in case info is NULL. Sponsored by: The FreeBSD Foundation MFC after: 3 days
This commit is contained in:
@@ -8304,6 +8304,9 @@ _lkpi_ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb,
|
|||||||
struct ieee80211_node *ni;
|
struct ieee80211_node *ni;
|
||||||
struct mbuf *m;
|
struct mbuf *m;
|
||||||
|
|
||||||
|
if (skb == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
m = skb->m;
|
m = skb->m;
|
||||||
skb->m = NULL;
|
skb->m = NULL;
|
||||||
|
|
||||||
@@ -8329,13 +8332,13 @@ linuxkpi_ieee80211_tx_status_ext(struct ieee80211_hw *hw,
|
|||||||
struct ieee80211_tx_status *txstat)
|
struct ieee80211_tx_status *txstat)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
struct ieee80211_tx_info *info;
|
struct ieee80211_tx_info *info, _info = { };
|
||||||
struct ieee80211_ratectl_tx_status txs;
|
struct ieee80211_ratectl_tx_status txs;
|
||||||
struct ieee80211_node *ni;
|
struct ieee80211_node *ni;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
skb = txstat->skb;
|
skb = txstat->skb;
|
||||||
if (skb->m != NULL) {
|
if (skb != NULL && skb->m != NULL) {
|
||||||
struct mbuf *m;
|
struct mbuf *m;
|
||||||
|
|
||||||
m = skb->m;
|
m = skb->m;
|
||||||
@@ -8345,7 +8348,13 @@ linuxkpi_ieee80211_tx_status_ext(struct ieee80211_hw *hw,
|
|||||||
ni = NULL;
|
ni = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we have no info information on tx, set info to an all-zero struct
|
||||||
|
* to make the code (and debug output) simpler.
|
||||||
|
*/
|
||||||
info = txstat->info;
|
info = txstat->info;
|
||||||
|
if (info == NULL)
|
||||||
|
info = &_info;
|
||||||
if (info->flags & IEEE80211_TX_STAT_ACK) {
|
if (info->flags & IEEE80211_TX_STAT_ACK) {
|
||||||
status = 0; /* No error. */
|
status = 0; /* No error. */
|
||||||
txs.status = IEEE80211_RATECTL_TX_SUCCESS;
|
txs.status = IEEE80211_RATECTL_TX_SUCCESS;
|
||||||
@@ -8410,7 +8419,8 @@ linuxkpi_ieee80211_tx_status_ext(struct ieee80211_hw *hw,
|
|||||||
|
|
||||||
if (txstat->free_list) {
|
if (txstat->free_list) {
|
||||||
_lkpi_ieee80211_free_txskb(hw, skb, status);
|
_lkpi_ieee80211_free_txskb(hw, skb, status);
|
||||||
list_add_tail(&skb->list, txstat->free_list);
|
if (skb != NULL)
|
||||||
|
list_add_tail(&skb->list, txstat->free_list);
|
||||||
} else {
|
} else {
|
||||||
linuxkpi_ieee80211_free_txskb(hw, skb, status);
|
linuxkpi_ieee80211_free_txskb(hw, skb, status);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user