summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAxel Lin <axel.lin@gmail.com>2010-05-31 08:04:47 +0800
committerGreg Kroah-Hartman <gregkh@suse.de>2010-07-05 11:22:49 -0700
commitf4723b721570bc97eeddc6c4aeea1e2be9f09afb (patch)
tree5f3f2ae7c3b321fc7a33cd0c12975d96ea246c59
parent7fcd12387f790caf53fc88bf57c443a9af9f2332 (diff)
USB: cdc-acm: fix resource reclaim in error path of acm_probe
commit c2572b78aa0447244a38e555ebb1b3b48a0088a5 upstream. 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> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/class/cdc-acm.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 5e1a253b08a0..3c73addaf79c 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/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);