ACK: [PATCH][SRU Zesty] net: hns: Fix a skb used after free bug
Stefan Bader
stefan.bader at canonical.com
Fri Jul 28 09:03:28 UTC 2017
On 18.07.2017 03:11, dann frazier wrote:
> From: Yunsheng Lin <linyunsheng at huawei.com>
>
> BugLink: https://bugs.launchpad.net/bugs/1704885
>
> skb maybe freed in hns_nic_net_xmit_hw() and return NETDEV_TX_OK,
> which cause hns_nic_net_xmit to use a freed skb.
>
> BUG: KASAN: use-after-free in hns_nic_net_xmit_hw+0x62c/0x940...
> [17659.112635] alloc_debug_processing+0x18c/0x1a0
> [17659.117208] __slab_alloc+0x52c/0x560
> [17659.120909] kmem_cache_alloc_node+0xac/0x2c0
> [17659.125309] __alloc_skb+0x6c/0x260
> [17659.128837] tcp_send_ack+0x8c/0x280
> [17659.132449] __tcp_ack_snd_check+0x9c/0xf0
> [17659.136587] tcp_rcv_established+0x5a4/0xa70
> [17659.140899] tcp_v4_do_rcv+0x27c/0x620
> [17659.144687] tcp_prequeue_process+0x108/0x170
> [17659.149085] tcp_recvmsg+0x940/0x1020
> [17659.152787] inet_recvmsg+0x124/0x180
> [17659.156488] sock_recvmsg+0x64/0x80
> [17659.160012] SyS_recvfrom+0xd8/0x180
> [17659.163626] __sys_trace_return+0x0/0x4
> [17659.167506] INFO: Freed in kfree_skbmem+0xa0/0xb0 age=23 cpu=1 pid=13
> [17659.174000] free_debug_processing+0x1d4/0x2c0
> [17659.178486] __slab_free+0x240/0x390
> [17659.182100] kmem_cache_free+0x24c/0x270
> [17659.186062] kfree_skbmem+0xa0/0xb0
> [17659.189587] __kfree_skb+0x28/0x40
> [17659.193025] napi_gro_receive+0x168/0x1c0
> [17659.197074] hns_nic_rx_up_pro+0x58/0x90
> [17659.201038] hns_nic_rx_poll_one+0x518/0xbc0
> [17659.205352] hns_nic_common_poll+0x94/0x140
> [17659.209576] net_rx_action+0x458/0x5e0
> [17659.213363] __do_softirq+0x1b8/0x480
> [17659.217062] run_ksoftirqd+0x64/0x80
> [17659.220679] smpboot_thread_fn+0x224/0x310
> [17659.224821] kthread+0x150/0x170
> [17659.228084] ret_from_fork+0x10/0x40
>
> BUG: KASAN: use-after-free in hns_nic_net_xmit+0x8c/0xc0...
> [17751.080490] __slab_alloc+0x52c/0x560
> [17751.084188] kmem_cache_alloc+0x244/0x280
> [17751.088238] __build_skb+0x40/0x150
> [17751.091764] build_skb+0x28/0x100
> [17751.095115] __alloc_rx_skb+0x94/0x150
> [17751.098900] __napi_alloc_skb+0x34/0x90
> [17751.102776] hns_nic_rx_poll_one+0x180/0xbc0
> [17751.107097] hns_nic_common_poll+0x94/0x140
> [17751.111333] net_rx_action+0x458/0x5e0
> [17751.115123] __do_softirq+0x1b8/0x480
> [17751.118823] run_ksoftirqd+0x64/0x80
> [17751.122437] smpboot_thread_fn+0x224/0x310
> [17751.126575] kthread+0x150/0x170
> [17751.129838] ret_from_fork+0x10/0x40
> [17751.133454] INFO: Freed in kfree_skbmem+0xa0/0xb0 age=19 cpu=7 pid=43
> [17751.139951] free_debug_processing+0x1d4/0x2c0
> [17751.144436] __slab_free+0x240/0x390
> [17751.148051] kmem_cache_free+0x24c/0x270
> [17751.152014] kfree_skbmem+0xa0/0xb0
> [17751.155543] __kfree_skb+0x28/0x40
> [17751.159022] napi_gro_receive+0x168/0x1c0
> [17751.163074] hns_nic_rx_up_pro+0x58/0x90
> [17751.167041] hns_nic_rx_poll_one+0x518/0xbc0
> [17751.171358] hns_nic_common_poll+0x94/0x140
> [17751.175585] net_rx_action+0x458/0x5e0
> [17751.179373] __do_softirq+0x1b8/0x480
> [17751.183076] run_ksoftirqd+0x64/0x80
> [17751.186691] smpboot_thread_fn+0x224/0x310
> [17751.190826] kthread+0x150/0x170
> [17751.194093] ret_from_fork+0x10/0x40
>
> Fixes: 13ac695e7ea1 ("net:hns: Add support of Hip06 SoC to the Hislicon Network Subsystem")
> Signed-off-by: Yunsheng Lin <linyunsheng at huawei.com>
> Signed-off-by: lipeng <lipeng321 at huawei.com>
> Reported-by: Jun He <hjat2005 at huawei.com>
> Signed-off-by: David S. Miller <davem at davemloft.net>
> (cherry picked from commit 27463ad99f738ed93c7c8b3e2e5bc8c4853a2ff2)
> Signed-off-by: dann frazier <dann.frazier at canonical.com>
Acked-by: Stefan Bader <stefan.bader at canonical.com>
> ---
> drivers/net/ethernet/hisilicon/hns/hns_enet.c | 22 ++++++++++------------
> drivers/net/ethernet/hisilicon/hns/hns_enet.h | 6 +++---
> 2 files changed, 13 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
> index 34dd3c6f1976..85505bac32d6 100644
> --- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
> +++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
> @@ -300,9 +300,9 @@ static void fill_tso_desc(struct hnae_ring *ring, void *priv,
> mtu);
> }
>
> -int hns_nic_net_xmit_hw(struct net_device *ndev,
> - struct sk_buff *skb,
> - struct hns_nic_ring_data *ring_data)
> +netdev_tx_t hns_nic_net_xmit_hw(struct net_device *ndev,
> + struct sk_buff *skb,
> + struct hns_nic_ring_data *ring_data)
> {
> struct hns_nic_priv *priv = netdev_priv(ndev);
> struct hnae_ring *ring = ring_data->ring;
> @@ -361,6 +361,10 @@ int hns_nic_net_xmit_hw(struct net_device *ndev,
> dev_queue = netdev_get_tx_queue(ndev, skb->queue_mapping);
> netdev_tx_sent_queue(dev_queue, skb->len);
>
> + netif_trans_update(ndev);
> + ndev->stats.tx_bytes += skb->len;
> + ndev->stats.tx_packets++;
> +
> 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);
> @@ -1477,17 +1481,11 @@ static netdev_tx_t hns_nic_net_xmit(struct sk_buff *skb,
> struct net_device *ndev)
> {
> struct hns_nic_priv *priv = netdev_priv(ndev);
> - int ret;
>
> assert(skb->queue_mapping < ndev->ae_handle->q_num);
> - ret = hns_nic_net_xmit_hw(ndev, skb,
> - &tx_ring_data(priv, skb->queue_mapping));
> - if (ret == NETDEV_TX_OK) {
> - netif_trans_update(ndev);
> - ndev->stats.tx_bytes += skb->len;
> - ndev->stats.tx_packets++;
> - }
> - return (netdev_tx_t)ret;
> +
> + return hns_nic_net_xmit_hw(ndev, skb,
> + &tx_ring_data(priv, skb->queue_mapping));
> }
>
> static void hns_nic_drop_rx_fetch(struct hns_nic_ring_data *ring_data,
> diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.h b/drivers/net/ethernet/hisilicon/hns/hns_enet.h
> index 1b83232082b2..9cb4c7884201 100644
> --- a/drivers/net/ethernet/hisilicon/hns/hns_enet.h
> +++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.h
> @@ -92,8 +92,8 @@ void hns_ethtool_set_ops(struct net_device *ndev);
> void hns_nic_net_reset(struct net_device *ndev);
> void hns_nic_net_reinit(struct net_device *netdev);
> int hns_nic_init_phy(struct net_device *ndev, struct hnae_handle *h);
> -int hns_nic_net_xmit_hw(struct net_device *ndev,
> - struct sk_buff *skb,
> - struct hns_nic_ring_data *ring_data);
> +netdev_tx_t hns_nic_net_xmit_hw(struct net_device *ndev,
> + struct sk_buff *skb,
> + struct hns_nic_ring_data *ring_data);
>
> #endif /**__HNS_ENET_H */
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <https://lists.ubuntu.com/archives/kernel-team/attachments/20170728/1a5bea1e/attachment.sig>
More information about the kernel-team
mailing list