aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/option.c
diff options
context:
space:
mode:
authorOliver Neukum <oneukum@suse.de>2007-03-20 08:41:21 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-04-27 16:28:37 -0400
commit7d28e74b97c8eb859fd9f5eb018bb1c75627bd55 (patch)
tree4c574a625a044bf3d6dc1ebd7cbacbb4a1f0732f /drivers/usb/serial/option.c
parent4f93b3e8212df43ff380e118aebb68f6d1e5b060 (diff)
USB: option close race
the option driver does not directly use usb_kill_urb(). It uses a wrapper. This wrapper means that callbacks which are running are not killed during close, resubmitting and illicitly pushing data into the tty layer. The whole purpose of usb_kill_urb() is subverted. The wrapper must be removed. Signed-off-by: Oliver Neukum <oneukum@suse.de> Signed-off-by: Matthias Urlichs <smurf@smurf.noris.de> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/serial/option.c')
-rw-r--r--drivers/usb/serial/option.c14
1 files changed, 4 insertions, 10 deletions
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index e178e6f40319..2846656d8358 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -591,12 +591,6 @@ static int option_open(struct usb_serial_port *port, struct file *filp)
591 return (0); 591 return (0);
592} 592}
593 593
594static inline void stop_urb(struct urb *urb)
595{
596 if (urb && urb->status == -EINPROGRESS)
597 usb_kill_urb(urb);
598}
599
600static void option_close(struct usb_serial_port *port, struct file *filp) 594static void option_close(struct usb_serial_port *port, struct file *filp)
601{ 595{
602 int i; 596 int i;
@@ -614,9 +608,9 @@ static void option_close(struct usb_serial_port *port, struct file *filp)
614 608
615 /* Stop reading/writing urbs */ 609 /* Stop reading/writing urbs */
616 for (i = 0; i < N_IN_URB; i++) 610 for (i = 0; i < N_IN_URB; i++)
617 stop_urb(portdata->in_urbs[i]); 611 usb_kill_urb(portdata->in_urbs[i]);
618 for (i = 0; i < N_OUT_URB; i++) 612 for (i = 0; i < N_OUT_URB; i++)
619 stop_urb(portdata->out_urbs[i]); 613 usb_kill_urb(portdata->out_urbs[i]);
620 } 614 }
621 port->tty = NULL; 615 port->tty = NULL;
622} 616}
@@ -747,9 +741,9 @@ static void option_shutdown(struct usb_serial *serial)
747 port = serial->port[i]; 741 port = serial->port[i];
748 portdata = usb_get_serial_port_data(port); 742 portdata = usb_get_serial_port_data(port);
749 for (j = 0; j < N_IN_URB; j++) 743 for (j = 0; j < N_IN_URB; j++)
750 stop_urb(portdata->in_urbs[j]); 744 usb_kill_urb(portdata->in_urbs[j]);
751 for (j = 0; j < N_OUT_URB; j++) 745 for (j = 0; j < N_OUT_URB; j++)
752 stop_urb(portdata->out_urbs[j]); 746 usb_kill_urb(portdata->out_urbs[j]);
753 } 747 }
754 748
755 /* Now free them */ 749 /* Now free them */