Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a34c72b3 authored by Alexey Khoroshilov's avatar Alexey Khoroshilov Committed by Greg Kroah-Hartman
Browse files

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: default avatarAlexey Khoroshilov <khoroshilov@ispras.ru>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 5e128475
Loading
Loading
Loading
Loading
+17 −23
Original line number Diff line number Diff line
@@ -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,22 +870,21 @@ 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:
	usb_get_dev(usbdev);
	usb_set_intfdata(intf, phy_dev);

	if (ret < 0) {
		kfree(phy_dev);
		if (udev) {
	return 0;

err_mac_address:
	release_usb(udev);
err_init_usb:
	kfree(udev);
		}
	}

	usb_get_dev(usbdev);
	usb_set_intfdata(intf, phy_dev);
err_udev:
	kfree(phy_dev);

	return ret;
}