Skip to content

Commit

Permalink
tty: Fix a USB serial crash/scribble
Browse files Browse the repository at this point in the history
The port lock is used to protect the port state. However the port structure
is freed on a hangup, then the lock taken on a close. The right fix is to
drop the port on tty->shutdown() but we can't yet do that due to sleep v
non-sleeping rules. Instead do the next best thing and fix it up when we are
not in -rc season.

Reported-by: Daniel Mack <daniel@caiaq.de>
Signed-off-by: Alan Cox <alan@linux.intel.com>
Tested-by: Daniel Mack <daniel@caiaq.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Alan Cox authored and Linus Torvalds committed Jul 27, 2009
1 parent 6a31d4a commit b68f2fb
Showing 1 changed file with 18 additions and 1 deletion.
19 changes: 18 additions & 1 deletion drivers/usb/serial/usb-serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,22 @@ static void serial_close(struct tty_struct *tty, struct file *filp)

dbg("%s - port %d", __func__, port->number);

/* FIXME:
This leaves a very narrow race. Really we should do the
serial_do_free() on tty->shutdown(), but tty->shutdown can
be called from IRQ context and serial_do_free can sleep.
The right fix is probably to make the tty free (which is rare)
and thus tty->shutdown() occur via a work queue and simplify all
the drivers that use it.
*/
if (tty_hung_up_p(filp)) {
/* serial_hangup already called serial_down at this point.
Another user may have already reopened the port but
serial_do_free is refcounted */
serial_do_free(port);
return;
}

if (tty_port_close_start(&port->port, tty, filp) == 0)
return;
Expand All @@ -355,7 +371,8 @@ static void serial_hangup(struct tty_struct *tty)
struct usb_serial_port *port = tty->driver_data;
serial_do_down(port);
tty_port_hangup(&port->port);
serial_do_free(port);
/* We must not free port yet - the USB serial layer depends on it's
continued existence */
}

static int serial_write(struct tty_struct *tty, const unsigned char *buf,
Expand Down

0 comments on commit b68f2fb

Please sign in to comment.