can: peak: fix bad memory access and free sequence

Fix for bad memory access while disconnecting. netdev is freed before
private data free, and dev is accessed after freeing netdev.

This makes a slub problem, and it raise kernel oops with slub debugger
config.

Signed-off-by: Jiho Chu <jiho.chu@samsung.com>
Cc: linux-stable <stable@vger.kernel.org>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
This commit is contained in:
추지호 2016-12-08 12:01:13 +00:00 committed by Marc Kleine-Budde
parent ec988ad78e
commit b67d0dd7d0
1 changed files with 4 additions and 2 deletions

View File

@ -870,23 +870,25 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
static void peak_usb_disconnect(struct usb_interface *intf) static void peak_usb_disconnect(struct usb_interface *intf)
{ {
struct peak_usb_device *dev; struct peak_usb_device *dev;
struct peak_usb_device *dev_prev_siblings;
/* unregister as many netdev devices as siblings */ /* unregister as many netdev devices as siblings */
for (dev = usb_get_intfdata(intf); dev; dev = dev->prev_siblings) { for (dev = usb_get_intfdata(intf); dev; dev = dev_prev_siblings) {
struct net_device *netdev = dev->netdev; struct net_device *netdev = dev->netdev;
char name[IFNAMSIZ]; char name[IFNAMSIZ];
dev_prev_siblings = dev->prev_siblings;
dev->state &= ~PCAN_USB_STATE_CONNECTED; dev->state &= ~PCAN_USB_STATE_CONNECTED;
strncpy(name, netdev->name, IFNAMSIZ); strncpy(name, netdev->name, IFNAMSIZ);
unregister_netdev(netdev); unregister_netdev(netdev);
free_candev(netdev);
kfree(dev->cmd_buf); kfree(dev->cmd_buf);
dev->next_siblings = NULL; dev->next_siblings = NULL;
if (dev->adapter->dev_free) if (dev->adapter->dev_free)
dev->adapter->dev_free(dev); dev->adapter->dev_free(dev);
free_candev(netdev);
dev_info(&intf->dev, "%s removed\n", name); dev_info(&intf->dev, "%s removed\n", name);
} }