| From 2435e8fe1e577c8c75e9c93a0605ad06ee58488c Mon Sep 17 00:00:00 2001 |
| From: Liubin Shu <shuliubin@huawei.com> |
| Date: Thu, 4 Apr 2019 16:46:42 +0800 |
| Subject: net: hns: fix KASAN: use-after-free in hns_nic_net_xmit_hw() |
| |
| [ Upstream commit 3a39a12ad364a9acd1038ba8da67cd8430f30de4 ] |
| |
| This patch is trying to fix the issue due to: |
| [27237.844750] BUG: KASAN: use-after-free in hns_nic_net_xmit_hw+0x708/0xa18[hns_enet_drv] |
| |
| After hnae_queue_xmit() in hns_nic_net_xmit_hw(), can be |
| interrupted by interruptions, and than call hns_nic_tx_poll_one() |
| to handle the new packets, and free the skb. So, when turn back to |
| hns_nic_net_xmit_hw(), calling skb->len will cause use-after-free. |
| |
| This patch update tx ring statistics in hns_nic_tx_poll_one() to |
| fix the bug. |
| |
| Signed-off-by: Liubin Shu <shuliubin@huawei.com> |
| Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com> |
| Signed-off-by: Yonglong Liu <liuyonglong@huawei.com> |
| Signed-off-by: Peng Li <lipeng321@huawei.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Sasha Levin (Microsoft) <sashal@kernel.org> |
| --- |
| drivers/net/ethernet/hisilicon/hns/hns_enet.c | 5 +++-- |
| 1 file changed, 3 insertions(+), 2 deletions(-) |
| |
| diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c |
| index 60e7d7ae3787..e5a7c0761dbd 100644 |
| --- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c |
| +++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c |
| @@ -376,8 +376,6 @@ netdev_tx_t hns_nic_net_xmit_hw(struct net_device *ndev, |
| wmb(); /* commit all data before submit */ |
| assert(skb->queue_mapping < priv->ae_handle->q_num); |
| hnae_queue_xmit(priv->ae_handle->qs[skb->queue_mapping], buf_num); |
| - ring->stats.tx_pkts++; |
| - ring->stats.tx_bytes += skb->len; |
| |
| return NETDEV_TX_OK; |
| |
| @@ -999,6 +997,9 @@ static int hns_nic_tx_poll_one(struct hns_nic_ring_data *ring_data, |
| /* issue prefetch for next Tx descriptor */ |
| prefetch(&ring->desc_cb[ring->next_to_clean]); |
| } |
| + /* update tx ring statistics. */ |
| + ring->stats.tx_pkts += pkts; |
| + ring->stats.tx_bytes += bytes; |
| |
| NETIF_TX_UNLOCK(ring); |
| |
| -- |
| 2.20.1 |
| |