diff options
| author | Alexey Khoroshilov <khoroshilov@ispras.ru> | 2014-11-29 01:29:10 +0300 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-05-25 11:54:53 +0300 |
| commit | d0f35e23dafa0185f979d0c70463caa658062264 (patch) | |
| tree | 6b5c0acc34ef557be5a25978673f2ec28fd3b687 | |
| parent | 3d355e2700282381bd2b27f58fe35e2d5d871dd5 (diff) | |
| download | linux-d0f35e23dafa0185f979d0c70463caa658062264.tar.xz | |
usbip: fix error handling in stub_probe()
commit 3ff67445750a84de67faaf52c6e1895cb09f2c56 upstream.
If usb_hub_claim_port() fails, no resources are deallocated and
if stub_add_files() fails, port is not released.
The patch fixes these issues and rearranges error handling code.
Found by Linux Driver Verification project (linuxtesting.org).
Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
Acked-by: Valentina Manea <valentina.manea.m@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
| -rw-r--r-- | drivers/usb/usbip/stub_dev.c | 26 |
1 files changed, 15 insertions, 11 deletions
diff --git a/drivers/usb/usbip/stub_dev.c b/drivers/usb/usbip/stub_dev.c index 678c7a147cb4..6276cc3e6ba9 100644 --- a/drivers/usb/usbip/stub_dev.c +++ b/drivers/usb/usbip/stub_dev.c @@ -313,7 +313,6 @@ static int stub_probe(struct usb_device *udev) { struct stub_device *sdev = NULL; const char *udev_busid = dev_name(&udev->dev); - int err = 0; struct bus_id_priv *busid_priv; int rc; @@ -374,23 +373,28 @@ static int stub_probe(struct usb_device *udev) (struct usb_dev_state *) udev); if (rc) { dev_dbg(&udev->dev, "unable to claim port\n"); - return rc; + goto err_port; } - err = stub_add_files(&udev->dev); - if (err) { + rc = stub_add_files(&udev->dev); + if (rc) { dev_err(&udev->dev, "stub_add_files for %s\n", udev_busid); - dev_set_drvdata(&udev->dev, NULL); - usb_put_dev(udev); - kthread_stop_put(sdev->ud.eh); - - busid_priv->sdev = NULL; - stub_device_free(sdev); - return err; + goto err_files; } busid_priv->status = STUB_BUSID_ALLOC; return 0; +err_files: + usb_hub_release_port(udev->parent, udev->portnum, + (struct usb_dev_state *) udev); +err_port: + dev_set_drvdata(&udev->dev, NULL); + usb_put_dev(udev); + kthread_stop_put(sdev->ud.eh); + + busid_priv->sdev = NULL; + stub_device_free(sdev); + return rc; } static void shutdown_busid(struct bus_id_priv *busid_priv) |
