diff options
author | Peter Hurley <peter@hurleysoftware.com> | 2014-09-10 15:06:35 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-09-24 00:19:36 -0400 |
commit | c274f6ef1c6665632767d32e4ab912aad839ce27 (patch) | |
tree | fb916689439d10e29c55abc4e0af24e38ec203ec /drivers/tty/tty_ioctl.c | |
parent | 136d5258b2bc4ffae99cb69874a76624c26fbfad (diff) |
tty: Hold termios_rwsem for tcflow(TCIxxx)
While transmitting a START/STOP char for tcflow(TCION/TCIOFF), prevent
a termios change. Otherwise, a garbage in-band flow control char
may be sent, if the termios change overlaps the transmission setup.
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/tty_ioctl.c')
-rw-r--r-- | drivers/tty/tty_ioctl.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index ad9120d1c0f1..62380ccf70fb 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c | |||
@@ -1164,17 +1164,21 @@ int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, | |||
1164 | spin_unlock_irq(&tty->flow_lock); | 1164 | spin_unlock_irq(&tty->flow_lock); |
1165 | break; | 1165 | break; |
1166 | case TCIOFF: | 1166 | case TCIOFF: |
1167 | down_read(&tty->termios_rwsem); | ||
1167 | if (STOP_CHAR(tty) != __DISABLED_CHAR) | 1168 | if (STOP_CHAR(tty) != __DISABLED_CHAR) |
1168 | return tty_send_xchar(tty, STOP_CHAR(tty)); | 1169 | retval = tty_send_xchar(tty, STOP_CHAR(tty)); |
1170 | up_read(&tty->termios_rwsem); | ||
1169 | break; | 1171 | break; |
1170 | case TCION: | 1172 | case TCION: |
1173 | down_read(&tty->termios_rwsem); | ||
1171 | if (START_CHAR(tty) != __DISABLED_CHAR) | 1174 | if (START_CHAR(tty) != __DISABLED_CHAR) |
1172 | return tty_send_xchar(tty, START_CHAR(tty)); | 1175 | retval = tty_send_xchar(tty, START_CHAR(tty)); |
1176 | up_read(&tty->termios_rwsem); | ||
1173 | break; | 1177 | break; |
1174 | default: | 1178 | default: |
1175 | return -EINVAL; | 1179 | return -EINVAL; |
1176 | } | 1180 | } |
1177 | return 0; | 1181 | return retval; |
1178 | case TCFLSH: | 1182 | case TCFLSH: |
1179 | retval = tty_check_change(tty); | 1183 | retval = tty_check_change(tty); |
1180 | if (retval) | 1184 | if (retval) |