aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/class/usblp.c
diff options
context:
space:
mode:
authorPete Zaitcev <zaitcev@redhat.com>2007-08-14 16:19:16 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-10-12 17:55:15 -0400
commit42cb967fd01b1f50374fdfa811f86db103eea532 (patch)
tree01edefaaa9ab8ca7ede7f912ed83dab4d14a92c4 /drivers/usb/class/usblp.c
parentc36d54ab380fb8edeaa22776af869c64bfda43bd (diff)
usblp: Fix a double kfree
If submit fails, slab hits a BUG() because of a double kfree. The today's lesson is, you cannot just slap USB_FREE_BUFFER on code without adjusting the error paths. The patch is made bigger by opportunistic refactoring. Signed-Off-By: Pete Zaitcev <zaitcev@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/class/usblp.c')
-rw-r--r--drivers/usb/class/usblp.c35
1 files changed, 23 insertions, 12 deletions
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index 3a0f8186d4bf..ad632f2d6f94 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -686,10 +686,30 @@ done:
686 return retval; 686 return retval;
687} 687}
688 688
689static struct urb *usblp_new_writeurb(struct usblp *usblp, int transfer_length)
690{
691 struct urb *urb;
692 char *writebuf;
693
694 if ((writebuf = kmalloc(transfer_length, GFP_KERNEL)) == NULL)
695 return NULL;
696 if ((urb = usb_alloc_urb(0, GFP_KERNEL)) == NULL) {
697 kfree(writebuf);
698 return NULL;
699 }
700
701 usb_fill_bulk_urb(urb, usblp->dev,
702 usb_sndbulkpipe(usblp->dev,
703 usblp->protocol[usblp->current_protocol].epwrite->bEndpointAddress),
704 writebuf, transfer_length, usblp_bulk_write, usblp);
705 urb->transfer_flags |= URB_FREE_BUFFER;
706
707 return urb;
708}
709
689static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) 710static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
690{ 711{
691 struct usblp *usblp = file->private_data; 712 struct usblp *usblp = file->private_data;
692 char *writebuf;
693 struct urb *writeurb; 713 struct urb *writeurb;
694 int rv; 714 int rv;
695 int transfer_length; 715 int transfer_length;
@@ -710,18 +730,11 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t
710 transfer_length = USBLP_BUF_SIZE; 730 transfer_length = USBLP_BUF_SIZE;
711 731
712 rv = -ENOMEM; 732 rv = -ENOMEM;
713 if ((writebuf = kmalloc(USBLP_BUF_SIZE, GFP_KERNEL)) == NULL) 733 if ((writeurb = usblp_new_writeurb(usblp, transfer_length)) == NULL)
714 goto raise_buf;
715 if ((writeurb = usb_alloc_urb(0, GFP_KERNEL)) == NULL)
716 goto raise_urb; 734 goto raise_urb;
717 usb_fill_bulk_urb(writeurb, usblp->dev,
718 usb_sndbulkpipe(usblp->dev,
719 usblp->protocol[usblp->current_protocol].epwrite->bEndpointAddress),
720 writebuf, transfer_length, usblp_bulk_write, usblp);
721 writeurb->transfer_flags |= URB_FREE_BUFFER;
722 usb_anchor_urb(writeurb, &usblp->urbs); 735 usb_anchor_urb(writeurb, &usblp->urbs);
723 736
724 if (copy_from_user(writebuf, 737 if (copy_from_user(writeurb->transfer_buffer,
725 buffer + writecount, transfer_length)) { 738 buffer + writecount, transfer_length)) {
726 rv = -EFAULT; 739 rv = -EFAULT;
727 goto raise_badaddr; 740 goto raise_badaddr;
@@ -780,8 +793,6 @@ raise_badaddr:
780 usb_unanchor_urb(writeurb); 793 usb_unanchor_urb(writeurb);
781 usb_free_urb(writeurb); 794 usb_free_urb(writeurb);
782raise_urb: 795raise_urb:
783 kfree(writebuf);
784raise_buf:
785raise_wait: 796raise_wait:
786collect_error: /* Out of raise sequence */ 797collect_error: /* Out of raise sequence */
787 mutex_unlock(&usblp->wmut); 798 mutex_unlock(&usblp->wmut);