summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOliver Neukum <oliver@neukum.org>2012-04-26 21:59:10 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-05-07 08:56:36 -0700
commit197d1155b07b582d9969f456f61ee07d632af7e1 (patch)
tree54e9966a3010df457cfbbd0f44bfdc83d4b84e22
parentca288ca1de5957cb50e170dcdb5375c0e6467405 (diff)
USB: cdc-wdm: fix race leading leading to memory corruption
commit 5c22837adca7c30b66121cf18ad3e160134268d4 upstream. This patch fixes a race whereby a pointer to a buffer would be overwritten while the buffer was in use leading to a double free and a memory leak. This causes crashes. This bug was introduced in 2.6.34 Signed-off-by: Oliver Neukum <oneukum@suse.de> Tested-by: Bjørn Mork <bjorn@mork.no> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/class/cdc-wdm.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index 76f061375e14..00b7bf9a20ce 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -108,8 +108,9 @@ static void wdm_out_callback(struct urb *urb)
spin_lock(&desc->iuspin);
desc->werr = urb->status;
spin_unlock(&desc->iuspin);
- clear_bit(WDM_IN_USE, &desc->flags);
kfree(desc->outbuf);
+ desc->outbuf = NULL;
+ clear_bit(WDM_IN_USE, &desc->flags);
wake_up(&desc->wait);
}
@@ -312,7 +313,7 @@ static ssize_t wdm_write
if (we < 0)
return -EIO;
- desc->outbuf = buf = kmalloc(count, GFP_KERNEL);
+ buf = kmalloc(count, GFP_KERNEL);
if (!buf) {
rv = -ENOMEM;
goto outnl;
@@ -376,10 +377,12 @@ static ssize_t wdm_write
req->wIndex = desc->inum;
req->wLength = cpu_to_le16(count);
set_bit(WDM_IN_USE, &desc->flags);
+ desc->outbuf = buf;
rv = usb_submit_urb(desc->command, GFP_KERNEL);
if (rv < 0) {
kfree(buf);
+ desc->outbuf = NULL;
clear_bit(WDM_IN_USE, &desc->flags);
dev_err(&desc->intf->dev, "Tx URB error: %d\n", rv);
} else {