summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOliver Neukum <oneukum@suse.de>2007-03-20 12:54:05 (GMT)
committerGreg Kroah-Hartman <gregkh@suse.de>2007-04-27 20:28:37 (GMT)
commitebcf3ede6d84bf8aeff4378035d3fb312ede8dc9 (patch)
tree06bbf9d37e53ed1eb3afaba4a5d35c755d03f26a
parent7d28e74b97c8eb859fd9f5eb018bb1c75627bd55 (diff)
downloadlinux-ebcf3ede6d84bf8aeff4378035d3fb312ede8dc9.tar.xz
USB: sierra close race
the sierra 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. The same problem as the option driver. Signed-off-by: Oliver Neukum <oneukum@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/serial/sierra.c14
1 files changed, 4 insertions, 10 deletions
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index ecedd83..4865aff 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -456,12 +456,6 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp)
return (0);
}
-static inline void stop_urb(struct urb *urb)
-{
- if (urb && urb->status == -EINPROGRESS)
- usb_kill_urb(urb);
-}
-
static void sierra_close(struct usb_serial_port *port, struct file *filp)
{
int i;
@@ -479,9 +473,9 @@ static void sierra_close(struct usb_serial_port *port, struct file *filp)
/* Stop reading/writing urbs */
for (i = 0; i < N_IN_URB; i++)
- stop_urb(portdata->in_urbs[i]);
+ usb_unlink_urb(portdata->in_urbs[i]);
for (i = 0; i < N_OUT_URB; i++)
- stop_urb(portdata->out_urbs[i]);
+ usb_unlink_urb(portdata->out_urbs[i]);
}
port->tty = NULL;
}
@@ -585,9 +579,9 @@ static void sierra_shutdown(struct usb_serial *serial)
port = serial->port[i];
portdata = usb_get_serial_port_data(port);
for (j = 0; j < N_IN_URB; j++)
- stop_urb(portdata->in_urbs[j]);
+ usb_unlink_urb(portdata->in_urbs[j]);
for (j = 0; j < N_OUT_URB; j++)
- stop_urb(portdata->out_urbs[j]);
+ usb_unlink_urb(portdata->out_urbs[j]);
}
/* Now free them */