From a34c72b348703da43d605441b86a61688ec19a0d Mon Sep 17 00:00:00 2001 From: Alexey Khoroshilov Date: Sat, 16 Nov 2013 00:46:24 +0400 Subject: staging: gdm724x: fix leak at failure path in gdm_usb_probe() 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 Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm724x/gdm_usb.c | 40 +++++++++++++++++---------------------- 1 file changed, 17 insertions(+), 23 deletions(-) (limited to 'drivers/staging/gdm724x') 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; } -- cgit v1.2.3-59-g8ed1b