فهرست منبع

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>
Christian Engelmayer 11 سال پیش
والد
کامیت
7f196caffb
1فایلهای تغییر یافته به همراه17 افزوده شده و 7 حذف شده
  1. 17 7
      drivers/usb/core/driver.c

+ 17 - 7
drivers/usb/core/driver.c

@@ -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);