diff options
author | Peter Hurley <peter@hurleysoftware.com> | 2016-04-09 18:56:32 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-04-30 09:26:55 -0700 |
commit | 49c02304fe97f88ee65f92368fe3f473201a7976 (patch) | |
tree | daf7c48631b43083a4007b7b82f53f47010bfe99 /drivers/tty | |
parent | 5c0517fefc92d636e409141ed75c29c3f1969107 (diff) |
serial: core: Expand port mutex section in uart_poll_init()
Prepare uart_poll_init() to safely dereference uart port; expand the
port mutex section to guarantee uart port remains valid until
uart_poll_init() completes.
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/serial/serial_core.c | 30 |
1 files changed, 15 insertions, 15 deletions
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 0c48051db172..53d8486a23d9 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2230,42 +2230,42 @@ static int uart_poll_init(struct tty_driver *driver, int line, char *options) { struct uart_driver *drv = driver->driver_state; struct uart_state *state = drv->state + line; + struct tty_port *tport; struct uart_port *port; int baud = 9600; int bits = 8; int parity = 'n'; int flow = 'n'; - int ret; + int ret = 0; - if (!state || !state->uart_port) + if (!state) return -1; + tport = &state->port; + mutex_lock(&tport->mutex); + port = state->uart_port; - if (!(port->ops->poll_get_char && port->ops->poll_put_char)) - return -1; + if (!(port->ops->poll_get_char && port->ops->poll_put_char)) { + ret = -1; + goto out; + } if (port->ops->poll_init) { - struct tty_port *tport = &state->port; - - ret = 0; - mutex_lock(&tport->mutex); /* * We don't set initialized as we only initialized the hw, * e.g. state->xmit is still uninitialized. */ if (!tty_port_initialized(tport)) ret = port->ops->poll_init(port); - mutex_unlock(&tport->mutex); - if (ret) - return ret; } - if (options) { + if (!ret && options) { uart_parse_options(options, &baud, &parity, &bits, &flow); - return uart_set_options(port, NULL, baud, parity, bits, flow); + ret = uart_set_options(port, NULL, baud, parity, bits, flow); } - - return 0; +out: + mutex_unlock(&tport->mutex); + return ret; } static int uart_poll_get_char(struct tty_driver *driver, int line) |