| From: David Vrabel <david.vrabel@citrix.com> |
| Date: Wed, 27 May 2015 15:46:10 +0100 |
| Subject: xen-netfront: properly destroy queues when removing device |
| |
| commit ad0681185770716523c81b156c44b9804d7b8ed2 upstream. |
| |
| xennet_remove() freed the queues before freeing the netdevice which |
| results in a use-after-free when free_netdev() tries to delete the |
| napi instances that have already been freed. |
| |
| Fix this by fully destroy the queues (which includes deleting the napi |
| instances) before freeing the netdevice. |
| |
| Signed-off-by: David Vrabel <david.vrabel@citrix.com> |
| Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| [bwh: Backported to 3.16: I already backported most of this along with |
| the later commit 74470954857c "xen-netfront: Delete rx_refill_timer in |
| xennet_disconnect_backend()"; don't move the del_timer_sync() again.] |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| --- a/drivers/net/xen-netfront.c |
| +++ b/drivers/net/xen-netfront.c |
| @@ -2294,7 +2294,6 @@ static const struct xenbus_device_id net |
| static int xennet_remove(struct xenbus_device *dev) |
| { |
| struct netfront_info *info = dev_get_drvdata(&dev->dev); |
| - unsigned int num_queues = info->netdev->real_num_tx_queues; |
| |
| dev_dbg(&dev->dev, "%s\n", dev->nodename); |
| |
| @@ -2302,11 +2301,7 @@ static int xennet_remove(struct xenbus_d |
| |
| unregister_netdev(info->netdev); |
| |
| - if (num_queues) { |
| - kfree(info->queues); |
| - info->queues = NULL; |
| - } |
| - |
| + xennet_destroy_queues(info); |
| xennet_free_netdev(info->netdev); |
| |
| return 0; |