net: atlantic: fix use after free kasan warn

skb->len is used to calculate statistics after xmit invocation.

Under a stress load it may happen that skb will be xmited,
rx interrupt will come and skb will be freed, all before xmit function
is even returned.

Eventually, skb->len will access unallocated area.

Moving stats calculation into tx_clean routine.

Fixes: 018423e90b ("net: ethernet: aquantia: Add ring support code")
Reported-by: Christophe Vu-Brugier <cvubrugier@fastmail.fm>
Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
Signed-off-by: Pavel Belous <pbelous@marvell.com>
Signed-off-by: Dmitry Bogdanov <dbogdanov@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Pavel Belous 2020-02-14 18:44:55 +03:00 committed by David S. Miller
parent b42726fcf7
commit a4980919ad
2 changed files with 5 additions and 6 deletions

View File

@ -655,10 +655,6 @@ int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb)
if (likely(frags)) { if (likely(frags)) {
err = self->aq_hw_ops->hw_ring_tx_xmit(self->aq_hw, err = self->aq_hw_ops->hw_ring_tx_xmit(self->aq_hw,
ring, frags); ring, frags);
if (err >= 0) {
++ring->stats.tx.packets;
ring->stats.tx.bytes += skb->len;
}
} else { } else {
err = NETDEV_TX_BUSY; err = NETDEV_TX_BUSY;
} }

View File

@ -272,9 +272,12 @@ bool aq_ring_tx_clean(struct aq_ring_s *self)
} }
} }
if (unlikely(buff->is_eop)) if (unlikely(buff->is_eop)) {
dev_kfree_skb_any(buff->skb); ++self->stats.rx.packets;
self->stats.tx.bytes += buff->skb->len;
dev_kfree_skb_any(buff->skb);
}
buff->pa = 0U; buff->pa = 0U;
buff->eop_index = 0xffffU; buff->eop_index = 0xffffU;
self->sw_head = aq_ring_next_dx(self, self->sw_head); self->sw_head = aq_ring_next_dx(self, self->sw_head);