aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/tty_ioctl.c
diff options
context:
space:
mode:
authorPeter Hurley <peter@hurleysoftware.com>2014-09-10 15:06:35 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-09-24 00:19:36 -0400
commitc274f6ef1c6665632767d32e4ab912aad839ce27 (patch)
treefb916689439d10e29c55abc4e0af24e38ec203ec /drivers/tty/tty_ioctl.c
parent136d5258b2bc4ffae99cb69874a76624c26fbfad (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.c10
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)