Browse Source

USB: cdc-acm: fix resource reclaim in error path of acm_probe

This patch fixes resource reclaim in error path of acm_probe:

1. In the case of "out of memory (read urbs usb_alloc_urb)\n")", there
   is no need to call acm_read_buffers_free(acm) here.  Fix it by goto
   alloc_fail6 instead of alloc_fail7.
2. In the case of "out of memory (write urbs usb_alloc_urb)",
   usb_alloc_urb may fail in any iteration of the for loop.  Current
   implementation does not properly free allocated snd->urb.  Fix it by
   goto alloc_fail8 instead of alloc_fail7.
3. In the case of device_create_file(&intf->dev,&dev_attr_iCountryCodeRelDate)
   fail, acm->country_codes is kfreed. As a result, device_remove_file
   for dev_attr_wCountryCodes will not be executed in acm_disconnect.
   Fix it by calling device_remove_file for dev_attr_wCountryCodes
   before goto skip_countries.

Signed-off-by: Axel Lin <axel.lin@gmail.com>
Acked-by: Oliver Neukum <oneukum@suse.de>
Cc: stable <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Axel Lin 15 years ago
parent
commit
c2572b78aa
1 changed files with 4 additions and 2 deletions
  1. 4 2
      drivers/usb/class/cdc-acm.c

+ 4 - 2
drivers/usb/class/cdc-acm.c

@@ -1201,7 +1201,7 @@ made_compressed_probe:
 		if (rcv->urb == NULL) {
 			dev_dbg(&intf->dev,
 				"out of memory (read urbs usb_alloc_urb)\n");
-			goto alloc_fail7;
+			goto alloc_fail6;
 		}
 
 		rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
@@ -1225,7 +1225,7 @@ made_compressed_probe:
 		if (snd->urb == NULL) {
 			dev_dbg(&intf->dev,
 				"out of memory (write urbs usb_alloc_urb)");
-			goto alloc_fail7;
+			goto alloc_fail8;
 		}
 
 		if (usb_endpoint_xfer_int(epwrite))
@@ -1264,6 +1264,7 @@ made_compressed_probe:
 		i = device_create_file(&intf->dev,
 						&dev_attr_iCountryCodeRelDate);
 		if (i < 0) {
+			device_remove_file(&intf->dev, &dev_attr_wCountryCodes);
 			kfree(acm->country_codes);
 			goto skip_countries;
 		}
@@ -1300,6 +1301,7 @@ alloc_fail8:
 		usb_free_urb(acm->wb[i].urb);
 alloc_fail7:
 	acm_read_buffers_free(acm);
+alloc_fail6:
 	for (i = 0; i < num_rx_buf; i++)
 		usb_free_urb(acm->ru[i].urb);
 	usb_free_urb(acm->ctrlurb);