Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c8d50041 authored by Alan Cox's avatar Alan Cox Committed by Linus Torvalds
Browse files

tty: fix close/hangup race



We can get a situation where a hangup occurs during or after a close. In
that case the ldisc gets disposed of by the close and the hangup then
explodes.

Signed-off-by: default avatarAlan Cox <alan@linux.intel.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent a3ca86ae
Loading
Loading
Loading
Loading
+15 −10
Original line number Diff line number Diff line
@@ -790,17 +790,20 @@ void tty_ldisc_hangup(struct tty_struct *tty)
	 * N_TTY.
	 */
	if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) {
		/* Avoid racing set_ldisc */
		/* Avoid racing set_ldisc or tty_ldisc_release */
		mutex_lock(&tty->ldisc_mutex);
		if (tty->ldisc) {	/* Not yet closed */
			/* Switch back to N_TTY */
			tty_ldisc_halt(tty);
			tty_ldisc_wait_idle(tty);
			tty_ldisc_reinit(tty);
			/* At this point we have a closed ldisc and we want to
			   reopen it. We could defer this to the next open but
		   it means auditing a lot of other paths so this is a FIXME */
			   it means auditing a lot of other paths so this is
			   a FIXME */
			WARN_ON(tty_ldisc_open(tty, tty->ldisc));
			tty_ldisc_enable(tty);
		}
		mutex_unlock(&tty->ldisc_mutex);
		tty_reset_termios(tty);
	}
@@ -865,6 +868,7 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty)

	tty_ldisc_wait_idle(tty);

	mutex_lock(&tty->ldisc_mutex);
	/*
	 * Now kill off the ldisc
	 */
@@ -875,6 +879,7 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty)

	/* Ensure the next open requests the N_TTY ldisc */
	tty_set_termios_ldisc(tty, N_TTY);
	mutex_unlock(&tty->ldisc_mutex);

	/* This will need doing differently if we need to lock */
	if (o_tty)