LinuxKPI: 802.11: plug mbuf leak
Now that we are doing VHT it is possible to overflow the mbufqs we use in the TX and RX paths. Check the return code of mbufq_enqueue() deal with any error accordingly and propagate it. Sponsored by: The FreeBSD Foundation MFC after: 3 days
This commit is contained in:
@@ -4519,6 +4519,7 @@ lkpi_ic_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
|
|||||||
const struct ieee80211_bpf_params *params __unused)
|
const struct ieee80211_bpf_params *params __unused)
|
||||||
{
|
{
|
||||||
struct lkpi_sta *lsta;
|
struct lkpi_sta *lsta;
|
||||||
|
int error;
|
||||||
|
|
||||||
lsta = ni->ni_drv_data;
|
lsta = ni->ni_drv_data;
|
||||||
LKPI_80211_LSTA_TXQ_LOCK(lsta);
|
LKPI_80211_LSTA_TXQ_LOCK(lsta);
|
||||||
@@ -4542,7 +4543,21 @@ lkpi_ic_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Queue the packet and enqueue the task to handle it. */
|
/* Queue the packet and enqueue the task to handle it. */
|
||||||
mbufq_enqueue(&lsta->txq, m);
|
error = mbufq_enqueue(&lsta->txq, m);
|
||||||
|
if (error != 0) {
|
||||||
|
LKPI_80211_LSTA_TXQ_UNLOCK(lsta);
|
||||||
|
/*
|
||||||
|
* Free the mbuf (do NOT release ni ref for the m_pkthdr.rcvif!
|
||||||
|
* ieee80211_raw_output() does that in case of error).
|
||||||
|
*/
|
||||||
|
m_free(m);
|
||||||
|
#ifdef LINUXKPI_DEBUG_80211
|
||||||
|
if (linuxkpi_debug_80211 & D80211_TRACE_TX)
|
||||||
|
ic_printf(ni->ni_ic, "%s: mbufq_enqueue failed: %d\n",
|
||||||
|
__func__, error);
|
||||||
|
#endif
|
||||||
|
return (ENETDOWN);
|
||||||
|
}
|
||||||
taskqueue_enqueue(taskqueue_thread, &lsta->txq_task);
|
taskqueue_enqueue(taskqueue_thread, &lsta->txq_task);
|
||||||
LKPI_80211_LSTA_TXQ_UNLOCK(lsta);
|
LKPI_80211_LSTA_TXQ_UNLOCK(lsta);
|
||||||
|
|
||||||
@@ -6416,7 +6431,7 @@ linuxkpi_ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
|
|||||||
struct ieee80211vap *vap;
|
struct ieee80211vap *vap;
|
||||||
struct ieee80211_hdr *hdr;
|
struct ieee80211_hdr *hdr;
|
||||||
struct lkpi_sta *lsta;
|
struct lkpi_sta *lsta;
|
||||||
int i, offset, ok;
|
int i, offset, ok, error;
|
||||||
uint8_t rssi;
|
uint8_t rssi;
|
||||||
bool is_beacon;
|
bool is_beacon;
|
||||||
|
|
||||||
@@ -6627,7 +6642,18 @@ linuxkpi_ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
mbufq_enqueue(&lhw->rxq, m);
|
error = mbufq_enqueue(&lhw->rxq, m);
|
||||||
|
if (error != 0) {
|
||||||
|
LKPI_80211_LHW_RXQ_UNLOCK(lhw);
|
||||||
|
m_freem(m);
|
||||||
|
counter_u64_add(ic->ic_ierrors, 1);
|
||||||
|
#ifdef LINUXKPI_DEBUG_80211
|
||||||
|
if (linuxkpi_debug_80211 & D80211_TRACE_RX)
|
||||||
|
ic_printf(ni->ni_ic, "%s: mbufq_enqueue failed: %d\n",
|
||||||
|
__func__, error);
|
||||||
|
#endif
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
taskqueue_enqueue(taskqueue_thread, &lhw->rxq_task);
|
taskqueue_enqueue(taskqueue_thread, &lhw->rxq_task);
|
||||||
LKPI_80211_LHW_RXQ_UNLOCK(lhw);
|
LKPI_80211_LHW_RXQ_UNLOCK(lhw);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user