<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel/linux.git/drivers/tty/n_tty.c, branch v4.4.171</title>
<subtitle>Linux kernel stable tree (mirror)</subtitle>
<id>https://git.radix-linux.su/kernel/linux.git/atom?h=v4.4.171</id>
<link rel='self' href='https://git.radix-linux.su/kernel/linux.git/atom?h=v4.4.171'/>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/'/>
<updated>2018-12-01T08:46:41+00:00</updated>
<entry>
<title>tty: wipe buffer if not echoing data</title>
<updated>2018-12-01T08:46:41+00:00</updated>
<author>
<name>Greg Kroah-Hartman</name>
<email>greg@kroah.com</email>
</author>
<published>2018-10-04T18:06:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=2b7e9180b4017a28867f27786266cbd4e4a7cf8b'/>
<id>urn:sha1:2b7e9180b4017a28867f27786266cbd4e4a7cf8b</id>
<content type='text'>
commit b97b3d9fb57860a60592859e332de7759fd54c2e upstream.

If we are not echoing the data to userspace or the console is in icanon
mode, then perhaps it is a "secret" so we should wipe it once we are
done with it.

This mirrors the logic that the audit code has.

Reported-by: aszlig &lt;aszlig@nix.build&gt;
Tested-by: Milan Broz &lt;gmazyland@gmail.com&gt;
Tested-by: Daniel Zatovic &lt;daniel.zatovic@gmail.com&gt;
Tested-by: aszlig &lt;aszlig@nix.build&gt;
Cc: Willy Tarreau &lt;w@1wt.eu&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
</entry>
<entry>
<title>n_tty: Access echo_* variables carefully.</title>
<updated>2018-07-11T14:03:47+00:00</updated>
<author>
<name>Tetsuo Handa</name>
<email>penguin-kernel@I-love.SAKURA.ne.jp</email>
</author>
<published>2018-05-26T00:53:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=80fbfb1ce6fdfdb265d4ab3b0b87a7c3cf8f6aff'/>
<id>urn:sha1:80fbfb1ce6fdfdb265d4ab3b0b87a7c3cf8f6aff</id>
<content type='text'>
commit ebec3f8f5271139df618ebdf8427e24ba102ba94 upstream.

syzbot is reporting stalls at __process_echoes() [1]. This is because
since ldata-&gt;echo_commit &lt; ldata-&gt;echo_tail becomes true for some reason,
the discard loop is serving as almost infinite loop. This patch tries to
avoid falling into ldata-&gt;echo_commit &lt; ldata-&gt;echo_tail situation by
making access to echo_* variables more carefully.

Since reset_buffer_flags() is called without output_lock held, it should
not touch echo_* variables. And omit a call to reset_buffer_flags() from
n_tty_open() by using vzalloc().

Since add_echo_byte() is called without output_lock held, it needs memory
barrier between storing into echo_buf[] and incrementing echo_head counter.
echo_buf() needs corresponding memory barrier before reading echo_buf[].
Lack of handling the possibility of not-yet-stored multi-byte operation
might be the reason of falling into ldata-&gt;echo_commit &lt; ldata-&gt;echo_tail
situation, for if I do WARN_ON(ldata-&gt;echo_commit == tail + 1) prior to
echo_buf(ldata, tail + 1), the WARN_ON() fires.

Also, explicitly masking with buffer for the former "while" loop, and
use ldata-&gt;echo_commit &gt; tail for the latter "while" loop.

[1] https://syzkaller.appspot.com/bug?id=17f23b094cd80df750e5b0f8982c521ee6bcbf40

Signed-off-by: Tetsuo Handa &lt;penguin-kernel@I-love.SAKURA.ne.jp&gt;
Reported-by: syzbot &lt;syzbot+108696293d7a21ab688f@syzkaller.appspotmail.com&gt;
Cc: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Cc: stable &lt;stable@vger.kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
</entry>
<entry>
<title>n_tty: Fix stall at n_tty_receive_char_special().</title>
<updated>2018-07-11T14:03:47+00:00</updated>
<author>
<name>Tetsuo Handa</name>
<email>penguin-kernel@I-love.SAKURA.ne.jp</email>
</author>
<published>2018-05-26T00:53:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=a1f75c3f3a79147441649ea96d3a0b58e13ded31'/>
<id>urn:sha1:a1f75c3f3a79147441649ea96d3a0b58e13ded31</id>
<content type='text'>
commit 3d63b7e4ae0dc5e02d28ddd2fa1f945defc68d81 upstream.

syzbot is reporting stalls at n_tty_receive_char_special() [1]. This is
because comparison is not working as expected since ldata-&gt;read_head can
change at any moment. Mitigate this by explicitly masking with buffer size
when checking condition for "while" loops.

[1] https://syzkaller.appspot.com/bug?id=3d7481a346958d9469bebbeb0537d5f056bdd6e8

Signed-off-by: Tetsuo Handa &lt;penguin-kernel@I-love.SAKURA.ne.jp&gt;
Reported-by: syzbot &lt;syzbot+18df353d7540aa6b5467@syzkaller.appspotmail.com&gt;
Fixes: bc5a5e3f45d04784 ("n_tty: Don't wrap input buffer indices at buffer size")
Cc: stable &lt;stable@vger.kernel.org&gt;
Cc: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
</entry>
<entry>
<title>tty: make n_tty_read() always abort if hangup is in progress</title>
<updated>2018-04-24T07:32:04+00:00</updated>
<author>
<name>Tejun Heo</name>
<email>tj@kernel.org</email>
</author>
<published>2018-02-13T15:38:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=12ed237ccc0518a867bb6ba8d624865dfb44620c'/>
<id>urn:sha1:12ed237ccc0518a867bb6ba8d624865dfb44620c</id>
<content type='text'>
commit 28b0f8a6962a24ed21737578f3b1b07424635c9e upstream.

A tty is hung up by __tty_hangup() setting file-&gt;f_op to
hung_up_tty_fops, which is skipped on ttys whose write operation isn't
tty_write().  This means that, for example, /dev/console whose write
op is redirected_tty_write() is never actually marked hung up.

Because n_tty_read() uses the hung up status to decide whether to
abort the waiting readers, the lack of hung-up marking can lead to the
following scenario.

 1. A session contains two processes.  The leader and its child.  The
    child ignores SIGHUP.

 2. The leader exits and starts disassociating from the controlling
    terminal (/dev/console).

 3. __tty_hangup() skips setting f_op to hung_up_tty_fops.

 4. SIGHUP is delivered and ignored.

 5. tty_ldisc_hangup() is invoked.  It wakes up the waits which should
    clear the read lockers of tty-&gt;ldisc_sem.

 6. The reader wakes up but because tty_hung_up_p() is false, it
    doesn't abort and goes back to sleep while read-holding
    tty-&gt;ldisc_sem.

 7. The leader progresses to tty_ldisc_lock() in tty_ldisc_hangup()
    and is now stuck in D sleep indefinitely waiting for
    tty-&gt;ldisc_sem.

The following is Alan's explanation on why some ttys aren't hung up.

 http://lkml.kernel.org/r/20171101170908.6ad08580@alans-desktop

 1. It broke the serial consoles because they would hang up and close
    down the hardware. With tty_port that *should* be fixable properly
    for any cases remaining.

 2. The console layer was (and still is) completely broken and doens't
    refcount properly. So if you turn on console hangups it breaks (as
    indeed does freeing consoles and half a dozen other things).

As neither can be fixed quickly, this patch works around the problem
by introducing a new flag, TTY_HUPPING, which is used solely to tell
n_tty_read() that hang-up is in progress for the console and the
readers should be aborted regardless of the hung-up status of the
device.

The following is a sample hung task warning caused by this issue.

  INFO: task agetty:2662 blocked for more than 120 seconds.
        Not tainted 4.11.3-dbg-tty-lockup-02478-gfd6c7ee-dirty #28
  "echo 0 &gt; /proc/sys/kernel/hung_task_timeout_secs" disables this message.
      0  2662      1 0x00000086
  Call Trace:
   __schedule+0x267/0x890
   schedule+0x36/0x80
   schedule_timeout+0x23c/0x2e0
   ldsem_down_write+0xce/0x1f6
   tty_ldisc_lock+0x16/0x30
   tty_ldisc_hangup+0xb3/0x1b0
   __tty_hangup+0x300/0x410
   disassociate_ctty+0x6c/0x290
   do_exit+0x7ef/0xb00
   do_group_exit+0x3f/0xa0
   get_signal+0x1b3/0x5d0
   do_signal+0x28/0x660
   exit_to_usermode_loop+0x46/0x86
   do_syscall_64+0x9c/0xb0
   entry_SYSCALL64_slow_path+0x25/0x25

The following is the repro.  Run "$PROG /dev/console".  The parent
process hangs in D state.

  #include &lt;sys/types.h&gt;
  #include &lt;sys/stat.h&gt;
  #include &lt;sys/wait.h&gt;
  #include &lt;sys/ioctl.h&gt;
  #include &lt;fcntl.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;errno.h&gt;
  #include &lt;signal.h&gt;
  #include &lt;time.h&gt;
  #include &lt;termios.h&gt;

  int main(int argc, char **argv)
  {
	  struct sigaction sact = { .sa_handler = SIG_IGN };
	  struct timespec ts1s = { .tv_sec = 1 };
	  pid_t pid;
	  int fd;

	  if (argc &lt; 2) {
		  fprintf(stderr, "test-hung-tty /dev/$TTY\n");
		  return 1;
	  }

	  /* fork a child to ensure that it isn't already the session leader */
	  pid = fork();
	  if (pid &lt; 0) {
		  perror("fork");
		  return 1;
	  }

	  if (pid &gt; 0) {
		  /* top parent, wait for everyone */
		  while (waitpid(-1, NULL, 0) &gt;= 0)
			  ;
		  if (errno != ECHILD)
			  perror("waitpid");
		  return 0;
	  }

	  /* new session, start a new session and set the controlling tty */
	  if (setsid() &lt; 0) {
		  perror("setsid");
		  return 1;
	  }

	  fd = open(argv[1], O_RDWR);
	  if (fd &lt; 0) {
		  perror("open");
		  return 1;
	  }

	  if (ioctl(fd, TIOCSCTTY, 1) &lt; 0) {
		  perror("ioctl");
		  return 1;
	  }

	  /* fork a child, sleep a bit and exit */
	  pid = fork();
	  if (pid &lt; 0) {
		  perror("fork");
		  return 1;
	  }

	  if (pid &gt; 0) {
		  nanosleep(&amp;ts1s, NULL);
		  printf("Session leader exiting\n");
		  exit(0);
	  }

	  /*
	   * The child ignores SIGHUP and keeps reading from the controlling
	   * tty.  Because SIGHUP is ignored, the child doesn't get killed on
	   * parent exit and the bug in n_tty makes the read(2) block the
	   * parent's control terminal hangup attempt.  The parent ends up in
	   * D sleep until the child is explicitly killed.
	   */
	  sigaction(SIGHUP, &amp;sact, NULL);
	  printf("Child reading tty\n");
	  while (1) {
		  char buf[1024];

		  if (read(fd, buf, sizeof(buf)) &lt; 0) {
			  perror("read");
			  return 1;
		  }
	  }

	  return 0;
  }

Signed-off-by: Tejun Heo &lt;tj@kernel.org&gt;
Cc: Alan Cox &lt;alan@llwyncelyn.cymru&gt;
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
</entry>
<entry>
<title>n_tty: fix EXTPROC vs ICANON interaction with TIOCINQ (aka FIONREAD)</title>
<updated>2018-01-02T19:33:28+00:00</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2017-12-21T01:57:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=2e3883922530aa25ecc23cc27bab1d3fda779f5a'/>
<id>urn:sha1:2e3883922530aa25ecc23cc27bab1d3fda779f5a</id>
<content type='text'>
commit 966031f340185eddd05affcf72b740549f056348 upstream.

We added support for EXTPROC back in 2010 in commit 26df6d13406d ("tty:
Add EXTPROC support for LINEMODE") and the intent was to allow it to
override some (all?) ICANON behavior.  Quoting from that original commit
message:

         There is a new bit in the termios local flag word, EXTPROC.
         When this bit is set, several aspects of the terminal driver
         are disabled.  Input line editing, character echo, and mapping
         of signals are all disabled.  This allows the telnetd to turn
         off these functions when in linemode, but still keep track of
         what state the user wants the terminal to be in.

but the problem turns out that "several aspects of the terminal driver
are disabled" is a bit ambiguous, and you can really confuse the n_tty
layer by setting EXTPROC and then causing some of the ICANON invariants
to no longer be maintained.

This fixes at least one such case (TIOCINQ) becoming unhappy because of
the confusion over whether ICANON really means ICANON when EXTPROC is set.

This basically makes TIOCINQ match the case of read: if EXTPROC is set,
we ignore ICANON.  Also, make sure to reset the ICANON state ie EXTPROC
changes, not just if ICANON changes.

Fixes: 26df6d13406d ("tty: Add EXTPROC support for LINEMODE")
Reported-by: Tetsuo Handa &lt;penguin-kernel@i-love.sakura.ne.jp&gt;
Reported-by: syzkaller &lt;syzkaller@googlegroups.com&gt;
Cc: Jiri Slaby &lt;jslaby@suse.com&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
</entry>
<entry>
<title>Fix OpenSSH pty regression on close</title>
<updated>2016-06-01T19:15:52+00:00</updated>
<author>
<name>Brian Bloniarz</name>
<email>brian.bloniarz@gmail.com</email>
</author>
<published>2016-03-06T21:16:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=71378785b6bbeea4098c0dfaca0571b06297224f'/>
<id>urn:sha1:71378785b6bbeea4098c0dfaca0571b06297224f</id>
<content type='text'>
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 &lt;tsi@tuyoix.net&gt;

Reported-by: Volth &lt;openssh@volth.com&gt;
Reported-by: Marc Aurele La France &lt;tsi@tuyoix.net&gt;
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 &lt;brian.bloniarz@gmail.com&gt;
Reviewed-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
</entry>
<entry>
<title>n_tty: Fix unsafe reference to "other" ldisc</title>
<updated>2016-02-17T20:31:02+00:00</updated>
<author>
<name>Peter Hurley</name>
<email>peter@hurleysoftware.com</email>
</author>
<published>2016-01-11T06:40:56+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=cccd9546e993ddcd10a482e43a821420cb09c05d'/>
<id>urn:sha1:cccd9546e993ddcd10a482e43a821420cb09c05d</id>
<content type='text'>
commit 6d27a63caad3f13e96cf065d2d96828c2006be6b upstream.

Although n_tty_check_unthrottle() has a valid ldisc reference (since
the tty core gets the ldisc ref in tty_read() before calling the line
discipline read() method), it does not have a valid ldisc reference to
the "other" pty of a pty pair. Since getting an ldisc reference for
tty-&gt;link essentially open-codes tty_wakeup(), just replace with the
equivalent tty_wakeup().

Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
</entry>
<entry>
<title>n_tty: Fix poll() after buffer-limited eof push read</title>
<updated>2015-12-13T05:42:31+00:00</updated>
<author>
<name>Peter Hurley</name>
<email>peter@hurleysoftware.com</email>
</author>
<published>2015-11-27T18:59:20+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=ac8f3bf8832a405cc6e4dccb1d26d5cb2994d234'/>
<id>urn:sha1:ac8f3bf8832a405cc6e4dccb1d26d5cb2994d234</id>
<content type='text'>
commit 40d5e0905a03 ("n_tty: Fix EOF push handling") fixed EOF push
for reads. However, that approach still allows a condition mismatch
between poll() and read(), where poll() returns POLLIN but read()
blocks. This state can happen when a previous read() returned because
the user buffer was full and the next character was an EOF not at the
beginning of the line. While the next read() will properly identify
the condition and advance the read buffer tail without improperly
indicating an EOF file condition (ie., read() will not mistakenly
return 0), poll() will mistakenly indicate POLLIN.

Although a possible solution would be to peek at the input buffer
in n_tty_poll(), the better solution in this patch is to eat the
EOF during the previous read() (ie., fix the problem by eliminating
the condition).

The current canon line buffer copy limits the scan for next end-of-line
to the smaller of either,
   a. the remaining user buffer size
   b. completed lines in the input buffer
When the remaining user buffer size is exactly one less than the
end-of-line marked by EOF push, the EOF is not scanned nor skipped
but left for subsequent reads. In the example below, the scan
index 'eol' has stopped at the EOF because it is past the scan
limit of 5 (not because it has found the next set bit in read_flags)

   user buffer [*nr = 5]    _ _ _ _ _

   read_flags               0 0 0 0 0   1
   input buffer             h e l l o [EOF]
                            ^           ^
                           /           /
                         tail        eol

   result: found = 0, tail += 5, *nr += 5

Instead, allow the scan to peek ahead 1 byte (while still limiting the
scan to completed lines in the input buffer). For the example above,

   result: found = 1, tail += 6, *nr += 5

Because the scan limit is now bumped +1 byte, when the scan is
completed, the tail advance and the user buffer copy limit is
re-clamped to *nr when EOF is _not_ found.

Fixes: 40d5e0905a03 ("n_tty: Fix EOF push handling")
Cc: &lt;stable@vger.kernel.org&gt; # 3.12+
Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>tty: audit: Fix audit source</title>
<updated>2015-11-21T00:19:54+00:00</updated>
<author>
<name>Peter Hurley</name>
<email>peter@hurleysoftware.com</email>
</author>
<published>2015-11-08T13:52:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=6b2a3d628aa752f0ab825fc6d4d07b09e274d1c1'/>
<id>urn:sha1:6b2a3d628aa752f0ab825fc6d4d07b09e274d1c1</id>
<content type='text'>
The data to audit/record is in the 'from' buffer (ie., the input
read buffer).

Fixes: 72586c6061ab ("n_tty: Fix auditing support for cannonical mode")
Cc: stable &lt;stable@vger.kernel.org&gt; # 4.1+
Cc: Miloslav Trmač &lt;mitr@redhat.com&gt;
Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Acked-by: Laura Abbott &lt;labbott@fedoraproject.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>tty: Abstract tty buffer work</title>
<updated>2015-10-18T04:32:21+00:00</updated>
<author>
<name>Peter Hurley</name>
<email>peter@hurleysoftware.com</email>
</author>
<published>2015-10-17T20:36:23+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=e176058f0de53c2346734e5254835e0045364001'/>
<id>urn:sha1:e176058f0de53c2346734e5254835e0045364001</id>
<content type='text'>
Introduce API functions to restart and cancel tty buffer work, rather
than manipulate buffer work directly.

Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
</feed>
