| From b67d0dd7d0dc9e456825447bbeb935d8ef43ea7c Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?=EC=B6=94=EC=A7=80=ED=98=B8?= <jiho.chu@samsung.com> |
| Date: Thu, 8 Dec 2016 12:01:13 +0000 |
| Subject: can: peak: fix bad memory access and free sequence |
| |
| From: 추지호 <jiho.chu@samsung.com> |
| |
| commit b67d0dd7d0dc9e456825447bbeb935d8ef43ea7c upstream. |
| |
| 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> |
| Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/net/can/usb/peak_usb/pcan_usb_core.c | 6 ++++-- |
| 1 file changed, 4 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c |
| +++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c |
| @@ -872,23 +872,25 @@ lbl_free_candev: |
| static void peak_usb_disconnect(struct usb_interface *intf) |
| { |
| struct peak_usb_device *dev; |
| + struct peak_usb_device *dev_prev_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; |
| char name[IFNAMSIZ]; |
| |
| + dev_prev_siblings = dev->prev_siblings; |
| dev->state &= ~PCAN_USB_STATE_CONNECTED; |
| strncpy(name, netdev->name, IFNAMSIZ); |
| |
| unregister_netdev(netdev); |
| - free_candev(netdev); |
| |
| kfree(dev->cmd_buf); |
| dev->next_siblings = NULL; |
| if (dev->adapter->dev_free) |
| dev->adapter->dev_free(dev); |
| |
| + free_candev(netdev); |
| dev_info(&intf->dev, "%s removed\n", name); |
| } |
| |