Skip to content

Commit

Permalink
n_tty: signal and flush atomically
Browse files Browse the repository at this point in the history
When handling signalling char, claim the termios write lock before
signalling waiting readers and writers to prevent further i/o
before flushing the echo and output buffers. This prevents a
userspace signal handler which may output from racing the terminal
flush.

Reference: Bugzilla #99351 ("Output truncated in ssh session after...")
Fixes: commit d2b6f44 ("n_tty: Fix signal handling flushes")
Reported-by: Filipe Brandenburger <filbranden@google.com>
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Peter Hurley authored and Greg Kroah-Hartman committed Jul 23, 2015
1 parent 52721d9 commit 3b19e03
Showing 1 changed file with 13 additions and 3 deletions.
16 changes: 13 additions & 3 deletions drivers/tty/n_tty.c
Original file line number Diff line number Diff line change
Expand Up @@ -1108,19 +1108,29 @@ static void eraser(unsigned char c, struct tty_struct *tty)
* Locking: ctrl_lock
*/

static void isig(int sig, struct tty_struct *tty)
static void __isig(int sig, struct tty_struct *tty)
{
struct n_tty_data *ldata = tty->disc_data;
struct pid *tty_pgrp = tty_get_pgrp(tty);
if (tty_pgrp) {
kill_pgrp(tty_pgrp, sig, 1);
put_pid(tty_pgrp);
}
}

if (!L_NOFLSH(tty)) {
static void isig(int sig, struct tty_struct *tty)
{
struct n_tty_data *ldata = tty->disc_data;

if (L_NOFLSH(tty)) {
/* signal only */
__isig(sig, tty);

} else { /* signal and flush */
up_read(&tty->termios_rwsem);
down_write(&tty->termios_rwsem);

__isig(sig, tty);

/* clear echo buffer */
mutex_lock(&ldata->output_lock);
ldata->echo_head = ldata->echo_tail = 0;
Expand Down

0 comments on commit 3b19e03

Please sign in to comment.