<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel/linux.git/drivers/tty/n_tty.c, branch v5.9.12</title>
<subtitle>Linux kernel stable tree (mirror)</subtitle>
<id>https://git.radix-linux.su/kernel/linux.git/atom?h=v5.9.12</id>
<link rel='self' href='https://git.radix-linux.su/kernel/linux.git/atom?h=v5.9.12'/>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/'/>
<updated>2020-02-23T19:14:50+00:00</updated>
<entry>
<title>n_tty: Distribute switch variables for initialization</title>
<updated>2020-02-23T19:14:50+00:00</updated>
<author>
<name>Kees Cook</name>
<email>keescook@chromium.org</email>
</author>
<published>2020-02-20T06:23:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=e24cd4e6d6aa3ca741cdfdfc01118c4016acebea'/>
<id>urn:sha1:e24cd4e6d6aa3ca741cdfdfc01118c4016acebea</id>
<content type='text'>
Variables declared in a switch statement before any case statements
cannot be automatically initialized with compiler instrumentation (as
they are not part of any execution flow). With GCC's proposed automatic
stack variable initialization feature, this triggers a warning (and they
don't get initialized). Clang's automatic stack variable initialization
(via CONFIG_INIT_STACK_ALL=y) doesn't throw a warning, but it also
doesn't initialize such variables[1]. Note that these warnings (or silent
skipping) happen before the dead-store elimination optimization phase,
so even when the automatic initializations are later elided in favor of
direct initializations, the warnings remain.

To avoid these problems, move such variables into the "case" where
they're used or lift them up into the main function body.

drivers/tty/n_tty.c: In function ‘__process_echoes’:
drivers/tty/n_tty.c:657:18: warning: statement will never be executed [-Wswitch-unreachable]
  657 |     unsigned int num_chars, num_bs;
      |                  ^~~~~~~~~

[1] https://bugs.llvm.org/show_bug.cgi?id=44916

Reviewed-by: Jiri Slaby &lt;jslaby@suse.cz&gt;
Signed-off-by: Kees Cook &lt;keescook@chromium.org&gt;
Link: https://lore.kernel.org/r/20200220062313.69209-1-keescook@chromium.org
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>n_tty: check printk arguments for n_tty_trace</title>
<updated>2020-02-10T20:34:43+00:00</updated>
<author>
<name>Jiri Slaby</name>
<email>jslaby@suse.cz</email>
</author>
<published>2020-01-30T11:58:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=a287885f1e378bff5f58cee6d0fd16b886c4863b'/>
<id>urn:sha1:a287885f1e378bff5f58cee6d0fd16b886c4863b</id>
<content type='text'>
When N_TTY_TRACE is undefined (the default), define n_tty_trace to use
no_printk. That way, arguments are still checked during compilation.

Signed-off-by: Jiri Slaby &lt;jslaby@suse.cz&gt;
Link: https://lore.kernel.org/r/20200130115843.7452-1-jslaby@suse.cz
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>n_tty: check for negative and zero space return from tty_write_room</title>
<updated>2019-04-16T13:21:33+00:00</updated>
<author>
<name>Colin Ian King</name>
<email>colin.king@canonical.com</email>
</author>
<published>2019-03-30T00:46:28+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=9ef8927f45f2f8e365cda7cda81c079f29b8ad74'/>
<id>urn:sha1:9ef8927f45f2f8e365cda7cda81c079f29b8ad74</id>
<content type='text'>
The return from tty_write_room could potentially be negative if
a tty write_room driver returns an error number (not that any seem
to do). Rather than just check for a zero return, also check for
a -ve return. This avoids the unsigned nr being set to a large unsigned
value on the assignment from variable space and can lead to overflowing
the buffer buf.  Better to be safe than assume all write_room
implementations in tty drivers are going to do the right thing.

Signed-off-by: Colin Ian King &lt;colin.king@canonical.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>n_tty: update comment for WAKEUP_CHARS define</title>
<updated>2019-01-18T12:25:11+00:00</updated>
<author>
<name>Valentin Vidic</name>
<email>Valentin.Vidic@CARNet.hr</email>
</author>
<published>2018-12-29T12:48:29+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=a5db482640c7b926357cf984701caafa8e0f8843'/>
<id>urn:sha1:a5db482640c7b926357cf984701caafa8e0f8843</id>
<content type='text'>
Give a better descriptions of what WAKEUP_CHARS represents.

Signed-off-by: Valentin Vidic &lt;Valentin.Vidic@CARNet.hr&gt;
Acked-by: Jiri Slaby &lt;jslaby@suse.cz&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>tty: Don't block on IO when ldisc change is pending</title>
<updated>2018-12-05T11:16:33+00:00</updated>
<author>
<name>Dmitry Safonov</name>
<email>dima@arista.com</email>
</author>
<published>2018-11-01T00:24:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=c96cf923a98d1b094df9f0cf97a83e118817e31b'/>
<id>urn:sha1:c96cf923a98d1b094df9f0cf97a83e118817e31b</id>
<content type='text'>
There might be situations where tty_ldisc_lock() has blocked, but there
is already IO on tty and it prevents line discipline changes.
It might theoretically turn into dead-lock.

Basically, provide more priority to pending tty_ldisc_lock() than to
servicing reads/writes over tty.

User-visible issue was reported by Mikulas where on pa-risc with
Debian 5 reboot took either 80 seconds, 3 minutes or 3:25 after proper
locking in tty_reopen().

Cc: Jiri Slaby &lt;jslaby@suse.com&gt;
Reported-by: Mikulas Patocka &lt;mpatocka@redhat.com&gt;
Signed-off-by: Dmitry Safonov &lt;dima@arista.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>tty: wipe buffer if not echoing data</title>
<updated>2018-10-11T17:50:00+00:00</updated>
<author>
<name>Greg KH</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=b97b3d9fb57860a60592859e332de7759fd54c2e'/>
<id>urn:sha1:b97b3d9fb57860a60592859e332de7759fd54c2e</id>
<content type='text'>
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-06-28T12:30:16+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=ebec3f8f5271139df618ebdf8427e24ba102ba94'/>
<id>urn:sha1:ebec3f8f5271139df618ebdf8427e24ba102ba94</id>
<content type='text'>
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-06-28T12:30:16+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=3d63b7e4ae0dc5e02d28ddd2fa1f945defc68d81'/>
<id>urn:sha1:3d63b7e4ae0dc5e02d28ddd2fa1f945defc68d81</id>
<content type='text'>
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-02-28T12:21:10+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=28b0f8a6962a24ed21737578f3b1b07424635c9e'/>
<id>urn:sha1:28b0f8a6962a24ed21737578f3b1b07424635c9e</id>
<content type='text'>
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>vfs: do bulk POLL* -&gt; EPOLL* replacement</title>
<updated>2018-02-11T22:34:03+00:00</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2018-02-11T22:34:03+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=a9a08845e9acbd224e4ee466f5c1275ed50054e8'/>
<id>urn:sha1:a9a08845e9acbd224e4ee466f5c1275ed50054e8</id>
<content type='text'>
This is the mindless scripted replacement of kernel use of POLL*
variables as described by Al, done by this script:

    for V in IN OUT PRI ERR RDNORM RDBAND WRNORM WRBAND HUP RDHUP NVAL MSG; do
        L=`git grep -l -w POLL$V | grep -v '^t' | grep -v /um/ | grep -v '^sa' | grep -v '/poll.h$'|grep -v '^D'`
        for f in $L; do sed -i "-es/^\([^\"]*\)\(\&lt;POLL$V\&gt;\)/\\1E\\2/" $f; done
    done

with de-mangling cleanups yet to come.

NOTE! On almost all architectures, the EPOLL* constants have the same
values as the POLL* constants do.  But they keyword here is "almost".
For various bad reasons they aren't the same, and epoll() doesn't
actually work quite correctly in some cases due to this on Sparc et al.

The next patch from Al will sort out the final differences, and we
should be all done.

Scripted-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
</feed>
