All of lore.kernel.org
 help / color / mirror / Atom feed
* USB: core: only clean up what we allocated
@ 2017-12-12 18:41 Andrey Konovalov
  0 siblings, 0 replies; 5+ messages in thread
From: Andrey Konovalov @ 2017-12-12 18:41 UTC (permalink / raw)
  To: Alan Stern; +Cc: Greg KH, USB list

On Tue, Dec 12, 2017 at 5:12 PM, Alan Stern <stern@rowland.harvard.edu> wrote:
> On Tue, 12 Dec 2017, Andrey Konovalov wrote:
>
>> On Tue, Dec 12, 2017 at 4:41 PM, Alan Stern <stern@rowland.harvard.edu> wrote:
>> > On Mon, 11 Dec 2017, Greg KH wrote:
>> >
>> >> From: Andrey Konovalov <andreyknvl@google.com>
>> >>
>> >> When cleaning up the configurations, make sure we only free the number
>> >> of configurations and interfaces that we could have allocated.
>> >>
>> >> Reported-by: Andrey Konovalov <andreyknvl@google.com>
>> >> Cc: stable <stable@vger.kernel.org>
>> >> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
>> >>
>> >> diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
>> >> index 55b198ba629b..93b38471754e 100644
>> >> --- a/drivers/usb/core/config.c
>> >> +++ b/drivers/usb/core/config.c
>> >> @@ -764,18 +764,21 @@ void usb_destroy_configuration(struct usb_device *dev)
>> >>               return;
>> >>
>> >>       if (dev->rawdescriptors) {
>> >> -             for (i = 0; i < dev->descriptor.bNumConfigurations; i++)
>> >> +             for (i = 0; i < dev->descriptor.bNumConfigurations &&
>> >> +                             i < USB_MAXCONFIG; i++)
>> >>                       kfree(dev->rawdescriptors[i]);
>> >>
>> >>               kfree(dev->rawdescriptors);
>> >>               dev->rawdescriptors = NULL;
>> >>       }
>> >>
>> >> -     for (c = 0; c < dev->descriptor.bNumConfigurations; c++) {
>> >> +     for (c = 0; c < dev->descriptor.bNumConfigurations &&
>> >> +                     c < USB_MAXCONFIG; c++) {
>> >>               struct usb_host_config *cf = &dev->config[c];
>> >>
>> >>               kfree(cf->string);
>> >> -             for (i = 0; i < cf->desc.bNumInterfaces; i++) {
>> >> +             for (i = 0; i < cf->desc.bNumInterfaces &&
>> >> +                             i < USB_MAXINTERFACES; i++) {
>> >>                       if (cf->intf_cache[i])
>> >>                               kref_put(&cf->intf_cache[i]->ref,
>> >>                                         usb_release_interface_cache);
>> >
>> > None of these changes are necessary.  The code is careful to reduce
>> > dev->descriptor.bNumConfigurations and config->desc.bNumInterfaces when
>> > necessary.
>> >
>> > In usb_get_configuration() (line 806 on my system):
>> >
>> >         if (ncfg > USB_MAXCONFIG) {
>> >                 dev_warn(ddev, "too many configurations: %d, "
>> >                     "using maximum allowed: %d\n", ncfg, USB_MAXCONFIG);
>> >                 dev->descriptor.bNumConfigurations = ncfg = USB_MAXCONFIG;
>> >         }
>> >
>> > In usb_parse_configuration() (line 676 on my system):
>> >
>> >         if (n != nintf)
>> >                 dev_warn(ddev, "config %d has %d interface%s, different from "
>> >                     "the descriptor's value: %d\n",
>> >                     cfgno, n, plural(n), nintf_orig);
>> >         else if (n == 0)
>> >                 dev_warn(ddev, "config %d has no interfaces?\n", cfgno);
>> >         config->desc.bNumInterfaces = nintf = n;
>>
>> usb_parse_configuration() might return before reducing
>> config->desc.bNumInterfaces, and usb_destroy_configuration() is still
>> called in this case.
>
> True.  Okay, how about this patch instead?

Looks good to me.

>
> Index: usb-4.x/drivers/usb/core/config.c
> ===================================================================
> --- usb-4.x.orig/drivers/usb/core/config.c
> +++ usb-4.x/drivers/usb/core/config.c
> @@ -555,6 +555,9 @@ static int usb_parse_configuration(struc
>         unsigned iad_num = 0;
>
>         memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE);
> +       nintf = nintf_orig = config->desc.bNumInterfaces;
> +       config->desc.bNumInterfaces = 0;        // Adjusted later
> +
>         if (config->desc.bDescriptorType != USB_DT_CONFIG ||
>             config->desc.bLength < USB_DT_CONFIG_SIZE ||
>             config->desc.bLength > size) {
> @@ -568,7 +571,6 @@ static int usb_parse_configuration(struc
>         buffer += config->desc.bLength;
>         size -= config->desc.bLength;
>
> -       nintf = nintf_orig = config->desc.bNumInterfaces;
>         if (nintf > USB_MAXINTERFACES) {
>                 dev_warn(ddev, "config %d has too many interfaces: %d, "
>                     "using maximum allowed: %d\n",
>
> Alan Stern
>
---
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 5+ messages in thread

* USB: core: only clean up what we allocated
@ 2017-12-12 16:12 Alan Stern
  0 siblings, 0 replies; 5+ messages in thread
From: Alan Stern @ 2017-12-12 16:12 UTC (permalink / raw)
  To: Andrey Konovalov; +Cc: Greg KH, USB list

On Tue, 12 Dec 2017, Andrey Konovalov wrote:

> On Tue, Dec 12, 2017 at 4:41 PM, Alan Stern <stern@rowland.harvard.edu> wrote:
> > On Mon, 11 Dec 2017, Greg KH wrote:
> >
> >> From: Andrey Konovalov <andreyknvl@google.com>
> >>
> >> When cleaning up the configurations, make sure we only free the number
> >> of configurations and interfaces that we could have allocated.
> >>
> >> Reported-by: Andrey Konovalov <andreyknvl@google.com>
> >> Cc: stable <stable@vger.kernel.org>
> >> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> >>
> >> diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
> >> index 55b198ba629b..93b38471754e 100644
> >> --- a/drivers/usb/core/config.c
> >> +++ b/drivers/usb/core/config.c
> >> @@ -764,18 +764,21 @@ void usb_destroy_configuration(struct usb_device *dev)
> >>               return;
> >>
> >>       if (dev->rawdescriptors) {
> >> -             for (i = 0; i < dev->descriptor.bNumConfigurations; i++)
> >> +             for (i = 0; i < dev->descriptor.bNumConfigurations &&
> >> +                             i < USB_MAXCONFIG; i++)
> >>                       kfree(dev->rawdescriptors[i]);
> >>
> >>               kfree(dev->rawdescriptors);
> >>               dev->rawdescriptors = NULL;
> >>       }
> >>
> >> -     for (c = 0; c < dev->descriptor.bNumConfigurations; c++) {
> >> +     for (c = 0; c < dev->descriptor.bNumConfigurations &&
> >> +                     c < USB_MAXCONFIG; c++) {
> >>               struct usb_host_config *cf = &dev->config[c];
> >>
> >>               kfree(cf->string);
> >> -             for (i = 0; i < cf->desc.bNumInterfaces; i++) {
> >> +             for (i = 0; i < cf->desc.bNumInterfaces &&
> >> +                             i < USB_MAXINTERFACES; i++) {
> >>                       if (cf->intf_cache[i])
> >>                               kref_put(&cf->intf_cache[i]->ref,
> >>                                         usb_release_interface_cache);
> >
> > None of these changes are necessary.  The code is careful to reduce
> > dev->descriptor.bNumConfigurations and config->desc.bNumInterfaces when
> > necessary.
> >
> > In usb_get_configuration() (line 806 on my system):
> >
> >         if (ncfg > USB_MAXCONFIG) {
> >                 dev_warn(ddev, "too many configurations: %d, "
> >                     "using maximum allowed: %d\n", ncfg, USB_MAXCONFIG);
> >                 dev->descriptor.bNumConfigurations = ncfg = USB_MAXCONFIG;
> >         }
> >
> > In usb_parse_configuration() (line 676 on my system):
> >
> >         if (n != nintf)
> >                 dev_warn(ddev, "config %d has %d interface%s, different from "
> >                     "the descriptor's value: %d\n",
> >                     cfgno, n, plural(n), nintf_orig);
> >         else if (n == 0)
> >                 dev_warn(ddev, "config %d has no interfaces?\n", cfgno);
> >         config->desc.bNumInterfaces = nintf = n;
> 
> usb_parse_configuration() might return before reducing
> config->desc.bNumInterfaces, and usb_destroy_configuration() is still
> called in this case.

True.  Okay, how about this patch instead?


Alan Stern
---
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Index: usb-4.x/drivers/usb/core/config.c
===================================================================
--- usb-4.x.orig/drivers/usb/core/config.c
+++ usb-4.x/drivers/usb/core/config.c
@@ -555,6 +555,9 @@ static int usb_parse_configuration(struc
 	unsigned iad_num = 0;
 
 	memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE);
+	nintf = nintf_orig = config->desc.bNumInterfaces;
+	config->desc.bNumInterfaces = 0;	// Adjusted later
+
 	if (config->desc.bDescriptorType != USB_DT_CONFIG ||
 	    config->desc.bLength < USB_DT_CONFIG_SIZE ||
 	    config->desc.bLength > size) {
@@ -568,7 +571,6 @@ static int usb_parse_configuration(struc
 	buffer += config->desc.bLength;
 	size -= config->desc.bLength;
 
-	nintf = nintf_orig = config->desc.bNumInterfaces;
 	if (nintf > USB_MAXINTERFACES) {
 		dev_warn(ddev, "config %d has too many interfaces: %d, "
 		    "using maximum allowed: %d\n",

^ permalink raw reply	[flat|nested] 5+ messages in thread

* USB: core: only clean up what we allocated
@ 2017-12-12 15:44 Andrey Konovalov
  0 siblings, 0 replies; 5+ messages in thread
From: Andrey Konovalov @ 2017-12-12 15:44 UTC (permalink / raw)
  To: Alan Stern; +Cc: Greg KH, USB list

On Tue, Dec 12, 2017 at 4:41 PM, Alan Stern <stern@rowland.harvard.edu> wrote:
> On Mon, 11 Dec 2017, Greg KH wrote:
>
>> From: Andrey Konovalov <andreyknvl@google.com>
>>
>> When cleaning up the configurations, make sure we only free the number
>> of configurations and interfaces that we could have allocated.
>>
>> Reported-by: Andrey Konovalov <andreyknvl@google.com>
>> Cc: stable <stable@vger.kernel.org>
>> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
>>
>> diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
>> index 55b198ba629b..93b38471754e 100644
>> --- a/drivers/usb/core/config.c
>> +++ b/drivers/usb/core/config.c
>> @@ -764,18 +764,21 @@ void usb_destroy_configuration(struct usb_device *dev)
>>               return;
>>
>>       if (dev->rawdescriptors) {
>> -             for (i = 0; i < dev->descriptor.bNumConfigurations; i++)
>> +             for (i = 0; i < dev->descriptor.bNumConfigurations &&
>> +                             i < USB_MAXCONFIG; i++)
>>                       kfree(dev->rawdescriptors[i]);
>>
>>               kfree(dev->rawdescriptors);
>>               dev->rawdescriptors = NULL;
>>       }
>>
>> -     for (c = 0; c < dev->descriptor.bNumConfigurations; c++) {
>> +     for (c = 0; c < dev->descriptor.bNumConfigurations &&
>> +                     c < USB_MAXCONFIG; c++) {
>>               struct usb_host_config *cf = &dev->config[c];
>>
>>               kfree(cf->string);
>> -             for (i = 0; i < cf->desc.bNumInterfaces; i++) {
>> +             for (i = 0; i < cf->desc.bNumInterfaces &&
>> +                             i < USB_MAXINTERFACES; i++) {
>>                       if (cf->intf_cache[i])
>>                               kref_put(&cf->intf_cache[i]->ref,
>>                                         usb_release_interface_cache);
>
> None of these changes are necessary.  The code is careful to reduce
> dev->descriptor.bNumConfigurations and config->desc.bNumInterfaces when
> necessary.
>
> In usb_get_configuration() (line 806 on my system):
>
>         if (ncfg > USB_MAXCONFIG) {
>                 dev_warn(ddev, "too many configurations: %d, "
>                     "using maximum allowed: %d\n", ncfg, USB_MAXCONFIG);
>                 dev->descriptor.bNumConfigurations = ncfg = USB_MAXCONFIG;
>         }
>
> In usb_parse_configuration() (line 676 on my system):
>
>         if (n != nintf)
>                 dev_warn(ddev, "config %d has %d interface%s, different from "
>                     "the descriptor's value: %d\n",
>                     cfgno, n, plural(n), nintf_orig);
>         else if (n == 0)
>                 dev_warn(ddev, "config %d has no interfaces?\n", cfgno);
>         config->desc.bNumInterfaces = nintf = n;

usb_parse_configuration() might return before reducing
config->desc.bNumInterfaces, and usb_destroy_configuration() is still
called in this case.

>
> Alan Stern
>
---
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 5+ messages in thread

* USB: core: only clean up what we allocated
@ 2017-12-12 15:41 Alan Stern
  0 siblings, 0 replies; 5+ messages in thread
From: Alan Stern @ 2017-12-12 15:41 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-usb, Andrey Konovalov

On Mon, 11 Dec 2017, Greg KH wrote:

> From: Andrey Konovalov <andreyknvl@google.com>
> 
> When cleaning up the configurations, make sure we only free the number
> of configurations and interfaces that we could have allocated.
> 
> Reported-by: Andrey Konovalov <andreyknvl@google.com>
> Cc: stable <stable@vger.kernel.org>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> 
> diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
> index 55b198ba629b..93b38471754e 100644
> --- a/drivers/usb/core/config.c
> +++ b/drivers/usb/core/config.c
> @@ -764,18 +764,21 @@ void usb_destroy_configuration(struct usb_device *dev)
>  		return;
>  
>  	if (dev->rawdescriptors) {
> -		for (i = 0; i < dev->descriptor.bNumConfigurations; i++)
> +		for (i = 0; i < dev->descriptor.bNumConfigurations &&
> +				i < USB_MAXCONFIG; i++)
>  			kfree(dev->rawdescriptors[i]);
>  
>  		kfree(dev->rawdescriptors);
>  		dev->rawdescriptors = NULL;
>  	}
>  
> -	for (c = 0; c < dev->descriptor.bNumConfigurations; c++) {
> +	for (c = 0; c < dev->descriptor.bNumConfigurations &&
> +			c < USB_MAXCONFIG; c++) {
>  		struct usb_host_config *cf = &dev->config[c];
>  
>  		kfree(cf->string);
> -		for (i = 0; i < cf->desc.bNumInterfaces; i++) {
> +		for (i = 0; i < cf->desc.bNumInterfaces &&
> +				i < USB_MAXINTERFACES; i++) {
>  			if (cf->intf_cache[i])
>  				kref_put(&cf->intf_cache[i]->ref,
>  					  usb_release_interface_cache);

None of these changes are necessary.  The code is careful to reduce
dev->descriptor.bNumConfigurations and config->desc.bNumInterfaces when
necessary.

In usb_get_configuration() (line 806 on my system):

	if (ncfg > USB_MAXCONFIG) {
		dev_warn(ddev, "too many configurations: %d, "
		    "using maximum allowed: %d\n", ncfg, USB_MAXCONFIG);
		dev->descriptor.bNumConfigurations = ncfg = USB_MAXCONFIG;
	}

In usb_parse_configuration() (line 676 on my system):

	if (n != nintf)
		dev_warn(ddev, "config %d has %d interface%s, different from "
		    "the descriptor's value: %d\n",
		    cfgno, n, plural(n), nintf_orig);
	else if (n == 0)
		dev_warn(ddev, "config %d has no interfaces?\n", cfgno);
	config->desc.bNumInterfaces = nintf = n;

Alan Stern
---
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 5+ messages in thread

* USB: core: only clean up what we allocated
@ 2017-12-11 21:48 Greg Kroah-Hartman
  0 siblings, 0 replies; 5+ messages in thread
From: Greg Kroah-Hartman @ 2017-12-11 21:48 UTC (permalink / raw)
  To: linux-usb; +Cc: Andrey Konovalov

From: Andrey Konovalov <andreyknvl@google.com>

When cleaning up the configurations, make sure we only free the number
of configurations and interfaces that we could have allocated.

Reported-by: Andrey Konovalov <andreyknvl@google.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index 55b198ba629b..93b38471754e 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -764,18 +764,21 @@ void usb_destroy_configuration(struct usb_device *dev)
 		return;
 
 	if (dev->rawdescriptors) {
-		for (i = 0; i < dev->descriptor.bNumConfigurations; i++)
+		for (i = 0; i < dev->descriptor.bNumConfigurations &&
+				i < USB_MAXCONFIG; i++)
 			kfree(dev->rawdescriptors[i]);
 
 		kfree(dev->rawdescriptors);
 		dev->rawdescriptors = NULL;
 	}
 
-	for (c = 0; c < dev->descriptor.bNumConfigurations; c++) {
+	for (c = 0; c < dev->descriptor.bNumConfigurations &&
+			c < USB_MAXCONFIG; c++) {
 		struct usb_host_config *cf = &dev->config[c];
 
 		kfree(cf->string);
-		for (i = 0; i < cf->desc.bNumInterfaces; i++) {
+		for (i = 0; i < cf->desc.bNumInterfaces &&
+				i < USB_MAXINTERFACES; i++) {
 			if (cf->intf_cache[i])
 				kref_put(&cf->intf_cache[i]->ref,
 					  usb_release_interface_cache);

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2017-12-12 18:41 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-12 18:41 USB: core: only clean up what we allocated Andrey Konovalov
  -- strict thread matches above, loose matches on Subject: below --
2017-12-12 16:12 Alan Stern
2017-12-12 15:44 Andrey Konovalov
2017-12-12 15:41 Alan Stern
2017-12-11 21:48 Greg Kroah-Hartman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.