diff options
author | Oliver Neukum <oliver@neukum.org> | 2012-04-26 21:59:10 +0200 |
---|---|---|
committer | Ben Hutchings <ben@decadent.org.uk> | 2012-05-11 13:14:41 +0100 |
commit | 670515c56290b7b7435f066e9bc0999fa1fc29b7 (patch) | |
tree | 1646e170519a62acefe85e91d540b964c30dee8d | |
parent | 54f74773233a4ac43bd5149aa2cb1734da37506b (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>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rw-r--r-- | drivers/usb/class/cdc-wdm.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 9eb71d8e1a2..2db0327db4f 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 { |