Make sure to free all the allocated memory before exiting from the function usb_get_configuration() when an error is encountered. Additionally, just initialize the variable "bigbuffer" with NULL to avoid the following build warning: CC drivers/usb/core/config.o drivers/usb/core/config.c: In function ‘usb_get_configuration’: drivers/usb/core/config.c:956:2: warning: ‘bigbuffer’ may be used uninitialized in this function [-Wmaybe-uninitialized] kfree(bigbuffer); ^ Signed-off-by: Tiezhu Yang <yangtiezhu@xxxxxxxxxxx> --- drivers/usb/core/config.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index bb63ee0..3763390 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -863,7 +863,7 @@ int usb_get_configuration(struct usb_device *dev) struct device *ddev = &dev->dev; int ncfg = dev->descriptor.bNumConfigurations; unsigned int cfgno, length; - unsigned char *bigbuffer; + unsigned char *bigbuffer = NULL; struct usb_config_descriptor *desc; int result = 0; @@ -885,12 +885,16 @@ int usb_get_configuration(struct usb_device *dev) length = ncfg * sizeof(char *); dev->rawdescriptors = kzalloc(length, GFP_KERNEL); - if (!dev->rawdescriptors) - return -ENOMEM; + if (!dev->rawdescriptors) { + result = -ENOMEM; + goto err_rawdescriptors; + } desc = kmalloc(USB_DT_CONFIG_SIZE, GFP_KERNEL); - if (!desc) - return -ENOMEM; + if (!desc) { + result = -ENOMEM; + goto err_desc; + } for (cfgno = 0; cfgno < ncfg; cfgno++) { /* We grab just the first descriptor so we know how long @@ -930,8 +934,7 @@ int usb_get_configuration(struct usb_device *dev) if (result < 0) { dev_err(ddev, "unable to read config index %d " "descriptor/%s\n", cfgno, "all"); - kfree(bigbuffer); - goto err; + goto out; } if (result < length) { dev_warn(ddev, "config index %d descriptor too short " @@ -945,13 +948,19 @@ int usb_get_configuration(struct usb_device *dev) &dev->config[cfgno], bigbuffer, length); if (result < 0) { ++cfgno; - goto err; + goto out; } } +out: + kfree(bigbuffer); err: kfree(desc); dev->descriptor.bNumConfigurations = cfgno; +err_desc: + kfree(dev->rawdescriptors); +err_rawdescriptors: + kfree(dev->config); return result; } -- 2.1.0