[<prev] [next>] [day] [month] [year] [list]
Date: Mon, 2 Mar 2020 21:48:33 -0500
From: Sasha Levin <sashal@...nel.org>
To: linux-kernel@...r.kernel.org, stable@...r.kernel.org
Cc: Pavel Belous <pbelous@...vell.com>,
Christophe Vu-Brugier <cvubrugier@...tmail.fm>,
Igor Russkikh <irusskikh@...vell.com>,
Dmitry Bogdanov <dbogdanov@...vell.com>,
"David S . Miller" <davem@...emloft.net>,
Sasha Levin <sashal@...nel.org>, netdev@...r.kernel.org
Subject: [PATCH AUTOSEL 4.19 14/32] net: atlantic: fix use after free kasan warn
From: Pavel Belous <pbelous@...vell.com>
[ Upstream commit a4980919ad6a7be548d499bc5338015e1a9191c6 ]
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: 018423e90bee ("net: ethernet: aquantia: Add ring support code")
Reported-by: Christophe Vu-Brugier <cvubrugier@...tmail.fm>
Signed-off-by: Igor Russkikh <irusskikh@...vell.com>
Signed-off-by: Pavel Belous <pbelous@...vell.com>
Signed-off-by: Dmitry Bogdanov <dbogdanov@...vell.com>
Signed-off-by: David S. Miller <davem@...emloft.net>
Signed-off-by: Sasha Levin <sashal@...nel.org>
---
drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 4 ----
drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 7 +++++--
2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index 8cc34b0bedc3a..d1de11b575f44 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -530,10 +530,6 @@ int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb)
if (likely(frags)) {
err = self->aq_hw_ops->hw_ring_tx_xmit(self->aq_hw,
ring, frags);
- if (err >= 0) {
- ++ring->stats.tx.packets;
- ring->stats.tx.bytes += skb->len;
- }
} else {
err = NETDEV_TX_BUSY;
}
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
index b3c7994d73eb1..b03e5fd4327e3 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
@@ -162,9 +162,12 @@ bool aq_ring_tx_clean(struct aq_ring_s *self)
}
}
- if (unlikely(buff->is_eop))
- dev_kfree_skb_any(buff->skb);
+ if (unlikely(buff->is_eop)) {
+ ++self->stats.rx.packets;
+ self->stats.tx.bytes += buff->skb->len;
+ dev_kfree_skb_any(buff->skb);
+ }
buff->pa = 0U;
buff->eop_index = 0xffffU;
self->sw_head = aq_ring_next_dx(self, self->sw_head);
--
2.20.1
Powered by blists - more mailing lists