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

Commit c8483bc9 authored by Peter Hurley's avatar Peter Hurley Committed by Greg Kroah-Hartman
Browse files

tty: Invert tty_lock/ldisc_sem lock order



Dropping the tty lock to acquire the tty->ldisc_sem allows several
race conditions (such as hangup while changing the ldisc) which requires
extra states and testing. The ldisc_sem->tty_lock lock order has
not been required since tty buffer ownership was moved to tty_port.

Reviewed-by: default avatarAlan Cox <alan@linux.intel.com>
Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 3ee175d9
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -523,9 +523,11 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
	if (IS_ERR(new_ldisc))
		return PTR_ERR(new_ldisc);

	tty_lock(tty);
	retval = tty_ldisc_lock_pair_timeout(tty, o_tty, 5 * HZ);
	if (retval) {
		tty_ldisc_put(new_ldisc);
		tty_unlock(tty);
		return retval;
	}

@@ -536,11 +538,11 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
	if (tty->ldisc->ops->num == ldisc) {
		tty_ldisc_enable_pair(tty, o_tty);
		tty_ldisc_put(new_ldisc);
		tty_unlock(tty);
		return 0;
	}

	old_ldisc = tty->ldisc;
	tty_lock(tty);

	if (test_bit(TTY_HUPPING, &tty->flags) ||
	    test_bit(TTY_HUPPED, &tty->flags)) {
@@ -675,8 +677,6 @@ void tty_ldisc_hangup(struct tty_struct *tty)
	wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
	wake_up_interruptible_poll(&tty->read_wait, POLLIN);

	tty_unlock(tty);

	/*
	 * Shutdown the current line discipline, and reset it to
	 * N_TTY if need be.
@@ -684,7 +684,6 @@ void tty_ldisc_hangup(struct tty_struct *tty)
	 * Avoid racing set_ldisc or tty_ldisc_release
	 */
	tty_ldisc_lock_pair(tty, tty->link);
	tty_lock(tty);

	if (tty->ldisc) {