From: Peter Hurley Date: Sun, 10 Apr 2016 01:56:32 +0000 (-0700) Subject: serial: core: Expand port mutex section in uart_poll_init() X-Git-Tag: v5.15~13571^2~74 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=49c02304fe97f88ee65f92368fe3f473201a7976;p=platform%2Fkernel%2Flinux-starfive.git 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 Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 0c48051..53d8486 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)