Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mwifiex: fix issues in driver unload path for USB chipsets

1) After driver load failure, clear 'card->adapter' instead of
card pointer so that card specific cleanup is performed later
when user unloads the driver.

2) Clear usb_card pointer in disconnect handler to avoid invalid
memory access when user unloads the driver after removing the
card.

Signed-off-by: Ujjal Roy <royujjal@gmail.com>
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by

Ujjal Roy and committed by
John W. Linville
353d2a69 3c59e328

+15 -12
+15 -12
drivers/net/wireless/mwifiex/usb.c
··· 350 350 351 351 card->udev = udev; 352 352 card->intf = intf; 353 - usb_card = card; 354 353 355 354 pr_debug("info: bcdUSB=%#x Device Class=%#x SubClass=%#x Protocol=%#x\n", 356 355 udev->descriptor.bcdUSB, udev->descriptor.bDeviceClass, ··· 524 525 static void mwifiex_usb_disconnect(struct usb_interface *intf) 525 526 { 526 527 struct usb_card_rec *card = usb_get_intfdata(intf); 527 - struct mwifiex_adapter *adapter; 528 528 529 - if (!card || !card->adapter) { 530 - pr_err("%s: card or card->adapter is NULL\n", __func__); 529 + if (!card) { 530 + pr_err("%s: card is NULL\n", __func__); 531 531 return; 532 532 } 533 533 534 - adapter = card->adapter; 535 - if (!adapter->priv_num) 536 - return; 537 - 538 534 mwifiex_usb_free(card); 539 535 540 - dev_dbg(adapter->dev, "%s: removing card\n", __func__); 541 - mwifiex_remove_card(adapter, &add_remove_card_sem); 536 + if (card->adapter) { 537 + struct mwifiex_adapter *adapter = card->adapter; 538 + 539 + if (!adapter->priv_num) 540 + return; 541 + 542 + dev_dbg(adapter->dev, "%s: removing card\n", __func__); 543 + mwifiex_remove_card(adapter, &add_remove_card_sem); 544 + } 542 545 543 546 usb_set_intfdata(intf, NULL); 544 547 usb_put_dev(interface_to_usbdev(intf)); 545 548 kfree(card); 549 + usb_card = NULL; 546 550 547 551 return; 548 552 } ··· 756 754 card->adapter = adapter; 757 755 adapter->dev = &card->udev->dev; 758 756 strcpy(adapter->fw_name, USB8797_DEFAULT_FW_NAME); 757 + usb_card = card; 759 758 760 759 return 0; 761 760 } ··· 765 762 { 766 763 struct usb_card_rec *card = (struct usb_card_rec *)adapter->card; 767 764 768 - usb_set_intfdata(card->intf, NULL); 765 + card->adapter = NULL; 769 766 } 770 767 771 768 static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, ··· 1007 1004 if (!down_interruptible(&add_remove_card_sem)) 1008 1005 up(&add_remove_card_sem); 1009 1006 1010 - if (usb_card) { 1007 + if (usb_card && usb_card->adapter) { 1011 1008 struct mwifiex_adapter *adapter = usb_card->adapter; 1012 1009 int i; 1013 1010