Error handling code in gdm_usb_probe() deallocates all resources, but calls usb_get_dev(usbdev) and returns error code after that.
The patch fixes it and, by the way, several other issues: - no need to use GFP_ATOMIC in probe(); - return -ENODEV instead of -1; - kmalloc+memset -> kzalloc Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov <khoroshi...@ispras.ru> --- drivers/staging/gdm724x/gdm_usb.c | 40 +++++++++++++++++---------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/drivers/staging/gdm724x/gdm_usb.c b/drivers/staging/gdm724x/gdm_usb.c index 781134af69d1..33458a583142 100644 --- a/drivers/staging/gdm724x/gdm_usb.c +++ b/drivers/staging/gdm724x/gdm_usb.c @@ -830,24 +830,19 @@ static int gdm_usb_probe(struct usb_interface *intf, const struct usb_device_id if (bInterfaceNumber > NETWORK_INTERFACE) { pr_info("not a network device\n"); - return -1; + return -ENODEV; } - phy_dev = kmalloc(sizeof(struct phy_dev), GFP_ATOMIC); - if (!phy_dev) { - ret = -ENOMEM; - goto out; - } + phy_dev = kzalloc(sizeof(struct phy_dev), GFP_KERNEL); + if (!phy_dev) + return -ENOMEM; - udev = kmalloc(sizeof(struct lte_udev), GFP_ATOMIC); + udev = kzalloc(sizeof(struct lte_udev), GFP_KERNEL); if (!udev) { ret = -ENOMEM; - goto out; + goto err_udev; } - memset(phy_dev, 0, sizeof(struct phy_dev)); - memset(udev, 0, sizeof(struct lte_udev)); - phy_dev->priv_dev = (void *)udev; phy_dev->send_hci_func = gdm_usb_hci_send; phy_dev->send_sdu_func = gdm_usb_sdu_send; @@ -858,7 +853,7 @@ static int gdm_usb_probe(struct usb_interface *intf, const struct usb_device_id ret = init_usb(udev); if (ret < 0) { pr_err("init_usb func failed\n"); - goto out; + goto err_init_usb; } udev->intf = intf; @@ -875,23 +870,22 @@ static int gdm_usb_probe(struct usb_interface *intf, const struct usb_device_id ret = request_mac_address(udev); if (ret < 0) { pr_err("request Mac address failed\n"); - goto out; + goto err_mac_address; } start_rx_proc(phy_dev); -out: - - if (ret < 0) { - kfree(phy_dev); - if (udev) { - release_usb(udev); - kfree(udev); - } - } - usb_get_dev(usbdev); usb_set_intfdata(intf, phy_dev); + return 0; + +err_mac_address: + release_usb(udev); +err_init_usb: + kfree(udev); +err_udev: + kfree(phy_dev); + return ret; } -- 1.8.1.2 _______________________________________________ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel