aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/tty/serial/8250
diff options
context:
space:
mode:
authorLukas Wunner <lukas@wunner.de>2020-02-28 14:31:01 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-03-07 09:52:01 +0100
commitf45709df7731ad36306a28a3e1af7309d55c35f5 (patch)
tree2aa45c7185e054b6e5f6007e324c878e67eaa1ac /drivers/tty/serial/8250
parentserial: earlycon: prefer EARLYCON_DECLARE() variant (diff)
downloadwireguard-linux-f45709df7731ad36306a28a3e1af7309d55c35f5.tar.xz
wireguard-linux-f45709df7731ad36306a28a3e1af7309d55c35f5.zip
serial: 8250: Don't touch RTS modem control while in rs485 mode
serial8250_do_set_mctrl() currently allows modifying the RTS modem control line even when RTS is used as an rs485 Transmit Enable signal. It is thus possible for user space to interfere with rs485 communication by invoking a TIOCMSET ioctl(). Ignore such change requests and retain the current RTS polarity when in rs485 mode. Note that serial8250_set_mctrl() is always called with port->lock held, so there's no risk that RTS is changed concurrently. Signed-off-by: Lukas Wunner <lukas@wunner.de> Cc: Matwey V. Kornilov <matwey@sai.msu.ru> Link: https://lore.kernel.org/r/b1ce34ca9bc4d7bdc6e9852fcf30b1f4e37c8a80.1582895077.git.lukas@wunner.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial/8250')
-rw-r--r--drivers/tty/serial/8250/8250_port.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index f398f162a1fd..a8f4cedde4dc 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -1924,6 +1924,13 @@ void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl)
struct uart_8250_port *up = up_to_u8250p(port);
unsigned char mcr;
+ if (port->rs485.flags & SER_RS485_ENABLED) {
+ if (serial8250_in_MCR(up) & UART_MCR_RTS)
+ mctrl |= TIOCM_RTS;
+ else
+ mctrl &= ~TIOCM_RTS;
+ }
+
mcr = serial8250_TIOCM_to_MCR(mctrl);
mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr;