Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752075AbbLMAiU (ORCPT ); Sat, 12 Dec 2015 19:38:20 -0500 Received: from mail-pa0-f45.google.com ([209.85.220.45]:36760 "EHLO mail-pa0-f45.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751437AbbLMAgv (ORCPT ); Sat, 12 Dec 2015 19:36:51 -0500 From: Peter Hurley To: Greg Kroah-Hartman Cc: Jiri Slaby , linux-kernel@vger.kernel.org, Peter Hurley Subject: [PATCH 5/8] serial: core: Expand port mutex section in uart_poll_init() Date: Sat, 12 Dec 2015 16:36:29 -0800 Message-Id: <1449966992-4033-6-git-send-email-peter@hurleysoftware.com> X-Mailer: git-send-email 2.6.3 In-Reply-To: <1449966992-4033-1-git-send-email-peter@hurleysoftware.com> References: <1449966992-4033-1-git-send-email-peter@hurleysoftware.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2418 Lines: 82 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 --- drivers/tty/serial/serial_core.c | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 806eba81..16c4c48 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2268,42 +2268,41 @@ 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 uart_port *port; + struct tty_port *port; + struct uart_port *uport; int baud = 9600; int bits = 8; int parity = 'n'; int flow = 'n'; - int ret; + int ret = -1; - if (!state || !state->uart_port) + if (!state) return -1; - port = state->uart_port; - if (!(port->ops->poll_get_char && port->ops->poll_put_char)) - return -1; + port = &state->port; + mutex_lock(&port->mutex); - if (port->ops->poll_init) { - struct tty_port *tport = &state->port; + uport = state->uart_port; + if (!(uport->ops->poll_get_char && uport->ops->poll_put_char)) + goto out; - ret = 0; - mutex_lock(&tport->mutex); + ret = 0; + if (uport->ops->poll_init) { /* * We don't set ASYNCB_INITIALIZED as we only initialized the * hw, e.g. state->xmit is still uninitialized. */ - if (!test_bit(ASYNCB_INITIALIZED, &tport->flags)) - ret = port->ops->poll_init(port); - mutex_unlock(&tport->mutex); - if (ret) - return ret; + if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) + ret = uport->ops->poll_init(uport); } - 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(uport, NULL, baud, parity, bits, flow); } - - return 0; +out: + mutex_unlock(&port->mutex); + return ret; } static int uart_poll_get_char(struct tty_driver *driver, int line) -- 2.6.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/