serdev: ttyport: fix NULL-deref on hangup
authorJohan Hovold <johan@kernel.org>
Fri, 3 Nov 2017 14:30:55 +0000 (15:30 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 14 Dec 2017 08:52:44 +0000 (09:52 +0100)
commit 8bcd4e6a8decac251d55c4377e2e67f052777ce0 upstream.

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")
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serdev/serdev-ttyport.c

index d4efe43544019b6e4a32ad31a1d40464011730cb..ce7fc44f2fe2a72c9c821146cc90134797df962c 100644 (file)
@@ -57,12 +57,19 @@ static void ttyport_write_wakeup(struct tty_port *port)
 {
        struct serdev_controller *ctrl = port->client_data;
        struct serport *serport = serdev_controller_get_drvdata(ctrl);
+       struct tty_struct *tty;
+
+       tty = tty_port_tty_get(port);
+       if (!tty)
+               return;
 
-       if (test_and_clear_bit(TTY_DO_WRITE_WAKEUP, &port->tty->flags) &&
+       if (test_and_clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
            test_bit(SERPORT_ACTIVE, &serport->flags))
                serdev_controller_write_wakeup(ctrl);
 
-       wake_up_interruptible_poll(&port->tty->write_wait, POLLOUT);
+       wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
+
+       tty_kref_put(tty);
 }
 
 static const struct tty_port_client_operations client_ops = {