Thread (315 messages) flat view 315 messages, 7 authors, 2016-11-12
STALE3552d REVIEWED: 1 (0M)

1 review trailer.

[PATCH 3.16 038/305] Fix OpenSSH pty regression on close

From: Ben Hutchings <hidden>
Date: 2016-08-14 11:48:18
Also in: lkml

3.16.37-rc1 review patch.  If anyone has any objections, please let me know.

------------------

From: Brian Bloniarz <redacted>

commit 0f40fbbcc34e093255a2b2d70b6b0fb48c3f39aa upstream.

OpenSSH expects the (non-blocking) read() of pty master to return
EAGAIN only if it has received all of the slave-side output after
it has received SIGCHLD. This used to work on pre-3.12 kernels.

This fix effectively forces non-blocking read() and poll() to
block for parallel i/o to complete for all ttys. It also unwinds
these changes:

1) f8747d4a466ab2cafe56112c51b3379f9fdb7a12
   tty: Fix pty master read() after slave closes

2) 52bce7f8d4fc633c9a9d0646eef58ba6ae9a3b73
   pty, n_tty: Simplify input processing on final close

3) 1a48632ffed61352a7810ce089dc5a8bcd505a60
   pty: Fix input race when closing

Inspired by analysis and patch from Marc Aurele La France [off-list ref]

Reported-by: Volth <redacted>
Reported-by: Marc Aurele La France <redacted>
BugLink: https://bugzilla.mindrot.org/show_bug.cgi?id=52
BugLink: https://bugzilla.mindrot.org/show_bug.cgi?id=2492
Signed-off-by: Brian Bloniarz <redacted>
Reviewed-by: Peter Hurley <redacted>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[bwh: Backported to 3.16:
 - No need to unwind commits 2 and 3
 - Keep using tty_flush_to_ldisc() rather than adding tty_buffer_flush_work()]]
Signed-off-by: Ben Hutchings <redacted>
---
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -2251,15 +2251,14 @@ static ssize_t n_tty_read(struct tty_str
 			ldata->minimum_to_wake = (minimum - (b - buf));
 
 		if (!input_available_p(tty, 0)) {
-			if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
-				up_read(&tty->termios_rwsem);
-				tty_flush_to_ldisc(tty);
-				down_read(&tty->termios_rwsem);
-				if (!input_available_p(tty, 0)) {
+			up_read(&tty->termios_rwsem);
+			tty_flush_to_ldisc(tty);
+			down_read(&tty->termios_rwsem);
+			if (!input_available_p(tty, 0)) {
+				if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
 					retval = -EIO;
 					break;
 				}
-			} else {
 				if (tty_hung_up_p(file))
 					break;
 				if (!timeout)
@@ -2467,6 +2466,11 @@ static unsigned int n_tty_poll(struct tt
 	poll_wait(file, &tty->write_wait, wait);
 	if (input_available_p(tty, 1))
 		mask |= POLLIN | POLLRDNORM;
+	else {
+		tty_flush_to_ldisc(tty);
+		if (input_available_p(tty, 1))
+			mask |= POLLIN | POLLRDNORM;
+	}
 	if (tty->packet && tty->link->ctrl_status)
 		mask |= POLLPRI | POLLIN | POLLRDNORM;
 	if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help