提交 7f196caf 编写于 作者: C Christian Engelmayer 提交者: Greg Kroah-Hartman

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: NChristian Engelmayer <cengelma@gmx.at>
Acked-by: NWolfram Sang <wsa@the-dreams.de>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
上级 76f24e3f
......@@ -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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册