diff options
| author | Johan Hovold <johan@kernel.org> | 2017-11-03 10:30:55 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-11-28 10:00:50 -0500 |
| commit | 8bcd4e6a8decac251d55c4377e2e67f052777ce0 (patch) | |
| tree | e9ecd5cb20a5a37a2f255d8d51622be7eec2b5de | |
| parent | fd00cf81a9a84776ba58e56bd042c726dcf75cf3 (diff) | |
serdev: ttyport: fix NULL-deref on hangup
Make sure to use a properly refcounted tty_struct in write_wake up to
avoid dereferencing a NULL-pointer when a port is being hung up.
Fixes: bed35c6dfa6a ("serdev: add a tty port controller driver")
Cc: stable <stable@vger.kernel.org> # 4.11
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
| -rw-r--r-- | drivers/tty/serdev/serdev-ttyport.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/tty/serdev/serdev-ttyport.c b/drivers/tty/serdev/serdev-ttyport.c index 09fbdd52a561..12cb9139073e 100644 --- a/drivers/tty/serdev/serdev-ttyport.c +++ b/drivers/tty/serdev/serdev-ttyport.c | |||
| @@ -49,12 +49,19 @@ static void ttyport_write_wakeup(struct tty_port *port) | |||
| 49 | { | 49 | { |
| 50 | struct serdev_controller *ctrl = port->client_data; | 50 | struct serdev_controller *ctrl = port->client_data; |
| 51 | struct serport *serport = serdev_controller_get_drvdata(ctrl); | 51 | struct serport *serport = serdev_controller_get_drvdata(ctrl); |
| 52 | struct tty_struct *tty; | ||
| 53 | |||
| 54 | tty = tty_port_tty_get(port); | ||
| 55 | if (!tty) | ||
| 56 | return; | ||
| 52 | 57 | ||
| 53 | if (test_and_clear_bit(TTY_DO_WRITE_WAKEUP, &port->tty->flags) && | 58 | if (test_and_clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && |
| 54 | test_bit(SERPORT_ACTIVE, &serport->flags)) | 59 | test_bit(SERPORT_ACTIVE, &serport->flags)) |
| 55 | serdev_controller_write_wakeup(ctrl); | 60 | serdev_controller_write_wakeup(ctrl); |
| 56 | 61 | ||
| 57 | wake_up_interruptible_poll(&port->tty->write_wait, POLLOUT); | 62 | wake_up_interruptible_poll(&tty->write_wait, POLLOUT); |
| 63 | |||
| 64 | tty_kref_put(tty); | ||
| 58 | } | 65 | } |
| 59 | 66 | ||
| 60 | static const struct tty_port_client_operations client_ops = { | 67 | static const struct tty_port_client_operations client_ops = { |
