diff options
author | Niklas Cassel <niklas.cassel@axis.com> | 2018-02-19 18:11:11 +0100 |
---|---|---|
committer | Vinod Koul <vkoul@kernel.org> | 2019-01-31 11:46:20 +0530 |
commit | 0640182f2ad16de9d5a0d298af2caf0a5ffa08ec (patch) | |
tree | 0c09899fc0ff0ace1a888fefca451eb751e38ea1 | |
parent | 4be334c45d7875c914bc2eee704692bc48f48764 (diff) |
net: stmmac: WARN if tx_skbuff entries are reused before cleared
The current code assumes that a tx_skbuff entry has been cleared
by stmmac_tx_clean() before stmmac_xmit()/stmmac_tso_xmit()
assigns a new skb to that entry. However, since we never check
the current value before overwriting it, it is theoretically
possible that a non-NULL value is overwritten.
Add WARN_ONs to verify that each entry in tx_skbuff is NULL
before it is assigned a new value.
Signed-off-by: Niklas Cassel <niklas.cassel@axis.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit b4c9784cbff43a2b50f6db6e2400c8d003c21546)
Signed-off-by: Vinod Koul <vkoul@kernel.org>
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index b5f9c66fee0c..9596c4e54834 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -2809,6 +2809,7 @@ static void stmmac_tso_allocator(struct stmmac_priv *priv, unsigned int des, while (tmp_len > 0) { tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, DMA_TX_SIZE); + WARN_ON(tx_q->tx_skbuff[tx_q->cur_tx]); desc = tx_q->dma_tx + tx_q->cur_tx; desc->des0 = cpu_to_le32(des + (total_len - tmp_len)); @@ -2893,6 +2894,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) priv->hw->desc->set_mss(mss_desc, mss); tx_q->mss = mss; tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, DMA_TX_SIZE); + WARN_ON(tx_q->tx_skbuff[tx_q->cur_tx]); } if (netif_msg_tx_queued(priv)) { @@ -2903,6 +2905,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) } first_entry = tx_q->cur_tx; + WARN_ON(tx_q->tx_skbuff[first_entry]); desc = tx_q->dma_tx + first_entry; first = desc; @@ -3085,6 +3088,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) entry = tx_q->cur_tx; first_entry = entry; + WARN_ON(tx_q->tx_skbuff[first_entry]); csum_insertion = (skb->ip_summed == CHECKSUM_PARTIAL); @@ -3113,6 +3117,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) bool last_segment = (i == (nfrags - 1)); entry = STMMAC_GET_ENTRY(entry, DMA_TX_SIZE); + WARN_ON(tx_q->tx_skbuff[entry]); if (likely(priv->extend_desc)) desc = (struct dma_desc *)(tx_q->dma_etx + entry); |