usbnet: fix memory leak in error case
commit b55a21b764c1e182014630fa5486d717484ac58f upstream.
usbnet_write_cmd_async() mixed up which buffers
need to be freed in which error case.
v2: add Fixes tag
v3: fix uninitialized buf pointer
Fixes: 877bd862f3
("usbnet: introduce usbnet 3 command helpers")
Signed-off-by: Oliver Neukum <oneukum@suse.com>
Link: https://lore.kernel.org/r/20220705125351.17309-1-oneukum@suse.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
e917be1f83
commit
0085da9df3
@@ -2102,7 +2102,7 @@ static void usbnet_async_cmd_cb(struct urb *urb)
|
|||||||
int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype,
|
int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype,
|
||||||
u16 value, u16 index, const void *data, u16 size)
|
u16 value, u16 index, const void *data, u16 size)
|
||||||
{
|
{
|
||||||
struct usb_ctrlrequest *req = NULL;
|
struct usb_ctrlrequest *req;
|
||||||
struct urb *urb;
|
struct urb *urb;
|
||||||
int err = -ENOMEM;
|
int err = -ENOMEM;
|
||||||
void *buf = NULL;
|
void *buf = NULL;
|
||||||
@@ -2120,7 +2120,7 @@ int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype,
|
|||||||
if (!buf) {
|
if (!buf) {
|
||||||
netdev_err(dev->net, "Error allocating buffer"
|
netdev_err(dev->net, "Error allocating buffer"
|
||||||
" in %s!\n", __func__);
|
" in %s!\n", __func__);
|
||||||
goto fail_free;
|
goto fail_free_urb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2144,14 +2144,21 @@ int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype,
|
|||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
netdev_err(dev->net, "Error submitting the control"
|
netdev_err(dev->net, "Error submitting the control"
|
||||||
" message: status=%d\n", err);
|
" message: status=%d\n", err);
|
||||||
goto fail_free;
|
goto fail_free_all;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
fail_free_all:
|
||||||
|
kfree(req);
|
||||||
fail_free_buf:
|
fail_free_buf:
|
||||||
kfree(buf);
|
kfree(buf);
|
||||||
fail_free:
|
/*
|
||||||
kfree(req);
|
* avoid a double free
|
||||||
|
* needed because the flag can be set only
|
||||||
|
* after filling the URB
|
||||||
|
*/
|
||||||
|
urb->transfer_flags = 0;
|
||||||
|
fail_free_urb:
|
||||||
usb_free_urb(urb);
|
usb_free_urb(urb);
|
||||||
fail:
|
fail:
|
||||||
return err;
|
return err;
|
||||||
|
Reference in New Issue
Block a user