Commit 98fa3189 authored by Peter Hurley's avatar Peter Hurley Committed by Kleber Sacilotto de Souza

tty: Handle NULL tty->ldisc

BugLink: http://bugs.launchpad.net/bugs/1709126

In preparation of destroying line discipline on hangup, fix
ldisc core operations to properly handle when the tty's ldisc is
NULL.
Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit a570a49a)
Signed-off-by: default avatarKamal Mostafa <kamal@canonical.com>
Acked-by: default avatarMarcelo Cerri <marcelo.cerri@canonical.com>
Acked-by: default avatarBenjamin M Romer <benjamin.romer@canonical.com>
Signed-off-by: default avatarKleber Sacilotto de Souza <kleber.souza@canonical.com>
parent cdff025c
...@@ -262,7 +262,8 @@ const struct file_operations tty_ldiscs_proc_fops = { ...@@ -262,7 +262,8 @@ const struct file_operations tty_ldiscs_proc_fops = {
struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty) struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty)
{ {
ldsem_down_read(&tty->ldisc_sem, MAX_SCHEDULE_TIMEOUT); ldsem_down_read(&tty->ldisc_sem, MAX_SCHEDULE_TIMEOUT);
WARN_ON(!tty->ldisc); if (!tty->ldisc)
ldsem_up_read(&tty->ldisc_sem);
return tty->ldisc; return tty->ldisc;
} }
EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait); EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait);
...@@ -455,7 +456,7 @@ static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld) ...@@ -455,7 +456,7 @@ static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld)
if (ret) if (ret)
clear_bit(TTY_LDISC_OPEN, &tty->flags); clear_bit(TTY_LDISC_OPEN, &tty->flags);
tty_ldisc_debug(tty, "%p: opened\n", tty->ldisc); tty_ldisc_debug(tty, "%p: opened\n", ld);
return ret; return ret;
} }
return 0; return 0;
...@@ -476,7 +477,7 @@ static void tty_ldisc_close(struct tty_struct *tty, struct tty_ldisc *ld) ...@@ -476,7 +477,7 @@ static void tty_ldisc_close(struct tty_struct *tty, struct tty_ldisc *ld)
clear_bit(TTY_LDISC_OPEN, &tty->flags); clear_bit(TTY_LDISC_OPEN, &tty->flags);
if (ld->ops->close) if (ld->ops->close)
ld->ops->close(tty); ld->ops->close(tty);
tty_ldisc_debug(tty, "%p: closed\n", tty->ldisc); tty_ldisc_debug(tty, "%p: closed\n", ld);
} }
/** /**
...@@ -539,6 +540,11 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) ...@@ -539,6 +540,11 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
if (retval) if (retval)
goto err; goto err;
if (!tty->ldisc) {
retval = -EIO;
goto out;
}
/* Check the no-op case */ /* Check the no-op case */
if (tty->ldisc->ops->num == ldisc) if (tty->ldisc->ops->num == ldisc)
goto out; goto out;
...@@ -654,7 +660,7 @@ void tty_ldisc_hangup(struct tty_struct *tty) ...@@ -654,7 +660,7 @@ void tty_ldisc_hangup(struct tty_struct *tty)
int reset = tty->driver->flags & TTY_DRIVER_RESET_TERMIOS; int reset = tty->driver->flags & TTY_DRIVER_RESET_TERMIOS;
int err = 0; int err = 0;
tty_ldisc_debug(tty, "%p: closing\n", tty->ldisc); tty_ldisc_debug(tty, "%p: hangup\n", tty->ldisc);
ld = tty_ldisc_ref(tty); ld = tty_ldisc_ref(tty);
if (ld != NULL) { if (ld != NULL) {
...@@ -738,6 +744,8 @@ int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty) ...@@ -738,6 +744,8 @@ int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty)
static void tty_ldisc_kill(struct tty_struct *tty) static void tty_ldisc_kill(struct tty_struct *tty)
{ {
if (!tty->ldisc)
return;
/* /*
* Now kill off the ldisc * Now kill off the ldisc
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment