<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel/linux.git/drivers/tty/n_tty.c, branch v4.4.8</title>
<subtitle>Linux kernel stable tree (mirror)</subtitle>
<id>https://git.radix-linux.su/kernel/linux.git/atom?h=v4.4.8</id>
<link rel='self' href='https://git.radix-linux.su/kernel/linux.git/atom?h=v4.4.8'/>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/'/>
<updated>2016-02-17T20:31:02+00:00</updated>
<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>
<entry>
<title>tty: Combine SIGTTOU/SIGTTIN handling</title>
<updated>2015-10-18T04:30:49+00:00</updated>
<author>
<name>Peter Hurley</name>
<email>peter@hurleysoftware.com</email>
</author>
<published>2015-10-11T00:28:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=2812d9e9fd94c54b0482215f579e6aa04452a322'/>
<id>urn:sha1:2812d9e9fd94c54b0482215f579e6aa04452a322</id>
<content type='text'>
The job_control() check in n_tty_read() has nearly identical purpose
and results as tty_check_change(). Both functions' purpose is to
determine if the current task's pgrp is the foreground pgrp for the tty,
and if not, to signal the current pgrp.

Introduce __tty_check_change() which takes the signal to send
and performs the shared operations for job control() and
tty_check_change().

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: Remove reader wakeups for TTY_BREAK/TTY_PARITY chars</title>
<updated>2015-10-18T04:18:30+00:00</updated>
<author>
<name>Peter Hurley</name>
<email>peter@hurleysoftware.com</email>
</author>
<published>2015-10-14T11:52:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=b3868e20f4ce21bb83c7a81bc50664d6a63596a8'/>
<id>urn:sha1:b3868e20f4ce21bb83c7a81bc50664d6a63596a8</id>
<content type='text'>
Waking the reader immediately upon receipt of TTY_BREAK or TTY_PARITY
chars has no effect on the outcome of read():
1. Only non-canonical/EXTPROC mode applies since canonical mode
   will not return data until a line termination is received anyway
2. EXTPROC mode - the reader will always be woken by the input worker
3. Non-canonical modes
   a. MIN == 0, TIME == 0
   b. MIN == 0, TIME &gt; 0
   c. MIN &gt; 0, TIME &gt; 0
      minimum_to_wake is always 1 in these modes so the reader will always
      be woken by the input worker
   d. MIN &gt; 0, TIME == 0
      although the reader will not be woken by the input worker unless the
      minimum data is received, the reader would not otherwise have
      returned the received data

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: fix stall caused by missing memory barrier in drivers/tty/n_tty.c</title>
<updated>2015-10-04T18:03:40+00:00</updated>
<author>
<name>Kosuke Tatsukawa</name>
<email>tatsu@ab.jp.nec.com</email>
</author>
<published>2015-10-02T08:27:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=e81107d4c6bd098878af9796b24edc8d4a9524fd'/>
<id>urn:sha1:e81107d4c6bd098878af9796b24edc8d4a9524fd</id>
<content type='text'>
My colleague ran into a program stall on a x86_64 server, where
n_tty_read() was waiting for data even if there was data in the buffer
in the pty.  kernel stack for the stuck process looks like below.
 #0 [ffff88303d107b58] __schedule at ffffffff815c4b20
 #1 [ffff88303d107bd0] schedule at ffffffff815c513e
 #2 [ffff88303d107bf0] schedule_timeout at ffffffff815c7818
 #3 [ffff88303d107ca0] wait_woken at ffffffff81096bd2
 #4 [ffff88303d107ce0] n_tty_read at ffffffff8136fa23
 #5 [ffff88303d107dd0] tty_read at ffffffff81368013
 #6 [ffff88303d107e20] __vfs_read at ffffffff811a3704
 #7 [ffff88303d107ec0] vfs_read at ffffffff811a3a57
 #8 [ffff88303d107f00] sys_read at ffffffff811a4306
 #9 [ffff88303d107f50] entry_SYSCALL_64_fastpath at ffffffff815c86d7

There seems to be two problems causing this issue.

First, in drivers/tty/n_tty.c, __receive_buf() stores the data and
updates ldata-&gt;commit_head using smp_store_release() and then checks
the wait queue using waitqueue_active().  However, since there is no
memory barrier, __receive_buf() could return without calling
wake_up_interactive_poll(), and at the same time, n_tty_read() could
start to wait in wait_woken() as in the following chart.

        __receive_buf()                         n_tty_read()
------------------------------------------------------------------------
if (waitqueue_active(&amp;tty-&gt;read_wait))
/* Memory operations issued after the
   RELEASE may be completed before the
   RELEASE operation has completed */
                                        add_wait_queue(&amp;tty-&gt;read_wait, &amp;wait);
                                        ...
                                        if (!input_available_p(tty, 0)) {
smp_store_release(&amp;ldata-&gt;commit_head,
                  ldata-&gt;read_head);
                                        ...
                                        timeout = wait_woken(&amp;wait,
                                          TASK_INTERRUPTIBLE, timeout);
------------------------------------------------------------------------

The second problem is that n_tty_read() also lacks a memory barrier
call and could also cause __receive_buf() to return without calling
wake_up_interactive_poll(), and n_tty_read() to wait in wait_woken()
as in the chart below.

        __receive_buf()                         n_tty_read()
------------------------------------------------------------------------
                                        spin_lock_irqsave(&amp;q-&gt;lock, flags);
                                        /* from add_wait_queue() */
                                        ...
                                        if (!input_available_p(tty, 0)) {
                                        /* Memory operations issued after the
                                           RELEASE may be completed before the
                                           RELEASE operation has completed */
smp_store_release(&amp;ldata-&gt;commit_head,
                  ldata-&gt;read_head);
if (waitqueue_active(&amp;tty-&gt;read_wait))
                                        __add_wait_queue(q, wait);
                                        spin_unlock_irqrestore(&amp;q-&gt;lock,flags);
                                        /* from add_wait_queue() */
                                        ...
                                        timeout = wait_woken(&amp;wait,
                                          TASK_INTERRUPTIBLE, timeout);
------------------------------------------------------------------------

There are also other places in drivers/tty/n_tty.c which have similar
calls to waitqueue_active(), so instead of adding many memory barrier
calls, this patch simply removes the call to waitqueue_active(),
leaving just wake_up*() behind.

This fixes both problems because, even though the memory access before
or after the spinlocks in both wake_up*() and add_wait_queue() can
sneak into the critical section, it cannot go past it and the critical
section assures that they will be serialized (please see "INTER-CPU
ACQUIRING BARRIER EFFECTS" in Documentation/memory-barriers.txt for a
better explanation).  Moreover, the resulting code is much simpler.

Latency measurement using a ping-pong test over a pty doesn't show any
visible performance drop.

Signed-off-by: Kosuke Tatsukawa &lt;tatsu@ab.jp.nec.com&gt;
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>Merge 4.2-rc4 into tty-next</title>
<updated>2015-07-27T18:12:39+00:00</updated>
<author>
<name>Greg Kroah-Hartman</name>
<email>gregkh@linuxfoundation.org</email>
</author>
<published>2015-07-27T18:12:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=92311e46ecf2298d87f175c8449ab4d8c400a38e'/>
<id>urn:sha1:92311e46ecf2298d87f175c8449ab4d8c400a38e</id>
<content type='text'>
Other serial driver work wants to build on patches now in 4.2-rc4 so
merge the branch so this can properly happen.

Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>tty: add missing rcu_read_lock for task_pgrp</title>
<updated>2015-07-24T00:56:38+00:00</updated>
<author>
<name>Patrick Donnelly</name>
<email>batrick@batbytes.com</email>
</author>
<published>2015-07-12T22:51:52+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=6719693ca2efb0f04654d05768ee299e87e1694b'/>
<id>urn:sha1:6719693ca2efb0f04654d05768ee299e87e1694b</id>
<content type='text'>
task_pgrp requires an rcu or tasklist lock to be obtained if the returned pid
is to be dereferenced, which kill_pgrp does. Obtain an RCU lock for the
duration of use.

Signed-off-by: Patrick Donnelly &lt;batrick@batbytes.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: signal and flush atomically</title>
<updated>2015-07-23T22:05:53+00:00</updated>
<author>
<name>Peter Hurley</name>
<email>peter@hurleysoftware.com</email>
</author>
<published>2015-06-27T13:21:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=3b19e032295647b7be2aa3be62510db4aaeda759'/>
<id>urn:sha1:3b19e032295647b7be2aa3be62510db4aaeda759</id>
<content type='text'>
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 d2b6f44779d3 ("n_tty: Fix signal handling flushes")
Reported-by: Filipe Brandenburger &lt;filbranden@google.com&gt;
Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
</feed>
