Commit ebcf3ede authored by Oliver Neukum's avatar Oliver Neukum Committed by Greg Kroah-Hartman
Browse files

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: default avatarOliver Neukum <oneukum@suse.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 7d28e74b
Loading
Loading
Loading
Loading
+4 −10
Original line number Original line Diff line number Diff line
@@ -456,12 +456,6 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp)
	return (0);
	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)
static void sierra_close(struct usb_serial_port *port, struct file *filp)
{
{
	int i;
	int i;
@@ -479,9 +473,9 @@ static void sierra_close(struct usb_serial_port *port, struct file *filp)


		/* Stop reading/writing urbs */
		/* Stop reading/writing urbs */
		for (i = 0; i < N_IN_URB; i++)
		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++)
		for (i = 0; i < N_OUT_URB; i++)
			stop_urb(portdata->out_urbs[i]);
			usb_unlink_urb(portdata->out_urbs[i]);
	}
	}
	port->tty = NULL;
	port->tty = NULL;
}
}
@@ -585,9 +579,9 @@ static void sierra_shutdown(struct usb_serial *serial)
		port = serial->port[i];
		port = serial->port[i];
		portdata = usb_get_serial_port_data(port);
		portdata = usb_get_serial_port_data(port);
		for (j = 0; j < N_IN_URB; j++)
		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++)
		for (j = 0; j < N_OUT_URB; j++)
			stop_urb(portdata->out_urbs[j]);
			usb_unlink_urb(portdata->out_urbs[j]);
	}
	}


	/* Now free them */
	/* Now free them */