mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-21 16:29:59 +00:00
usb: core: Fix potential memory leak adding dyn USBdevice IDs
Fix a memory leak in the usb_store_new_id() error paths. When bailing out due to sanity checks, the function left the already allocated usb_dynid struct in place. This regression was introduced by the following commits:c63fe8f6
(usb: core: add sanity checks when using bInterfaceClass with new_id)1b9fb31f
(usb: core: check for valid id_table when using the RefId feature)52a6966c
(usb: core: bail out if user gives an unknown RefId when using new_id) Detected by Coverity: CID 1162604. Signed-off-by: Christian Engelmayer <cengelma@gmx.at> Acked-by: Wolfram Sang <wsa@the-dreams.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
76f24e3f39
commit
7f196caffb
1 changed files with 17 additions and 7 deletions
|
@ -63,8 +63,10 @@ ssize_t usb_store_new_id(struct usb_dynids *dynids,
|
|||
dynid->id.idProduct = idProduct;
|
||||
dynid->id.match_flags = USB_DEVICE_ID_MATCH_DEVICE;
|
||||
if (fields > 2 && bInterfaceClass) {
|
||||
if (bInterfaceClass > 255)
|
||||
return -EINVAL;
|
||||
if (bInterfaceClass > 255) {
|
||||
retval = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
dynid->id.bInterfaceClass = (u8)bInterfaceClass;
|
||||
dynid->id.match_flags |= USB_DEVICE_ID_MATCH_INT_CLASS;
|
||||
|
@ -73,17 +75,21 @@ ssize_t usb_store_new_id(struct usb_dynids *dynids,
|
|||
if (fields > 4) {
|
||||
const struct usb_device_id *id = id_table;
|
||||
|
||||
if (!id)
|
||||
return -ENODEV;
|
||||
if (!id) {
|
||||
retval = -ENODEV;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (; id->match_flags; id++)
|
||||
if (id->idVendor == refVendor && id->idProduct == refProduct)
|
||||
break;
|
||||
|
||||
if (id->match_flags)
|
||||
if (id->match_flags) {
|
||||
dynid->id.driver_info = id->driver_info;
|
||||
else
|
||||
return -ENODEV;
|
||||
} else {
|
||||
retval = -ENODEV;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
spin_lock(&dynids->lock);
|
||||
|
@ -95,6 +101,10 @@ ssize_t usb_store_new_id(struct usb_dynids *dynids,
|
|||
if (retval)
|
||||
return retval;
|
||||
return count;
|
||||
|
||||
fail:
|
||||
kfree(dynid);
|
||||
return retval;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_store_new_id);
|
||||
|
||||
|
|
Loading…
Reference in a new issue