<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux-stable.git/drivers/char, branch linux-2.6.32.y</title>
<subtitle>Linux kernel stable tree</subtitle>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/'/>
<entry>
<title>tty: Fix unsafe ldisc reference via ioctl(TIOCGETD)</title>
<updated>2016-03-12T13:25:40+00:00</updated>
<author>
<name>Peter Hurley</name>
<email>peter@hurleysoftware.com</email>
</author>
<published>2016-01-11T06:40:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=f8b1cc043cd3db134db393979eb38b3141090efb'/>
<id>f8b1cc043cd3db134db393979eb38b3141090efb</id>
<content type='text'>
commit 5c17c861a357e9458001f021a7afa7aab9937439 upstream.

ioctl(TIOCGETD) retrieves the line discipline id directly from the
ldisc because the line discipline id (c_line) in termios is untrustworthy;
userspace may have set termios via ioctl(TCSETS*) without actually
changing the line discipline via ioctl(TIOCSETD).

However, directly accessing the current ldisc via tty-&gt;ldisc is
unsafe; the ldisc ptr dereferenced may be stale if the line discipline
is changing via ioctl(TIOCSETD) or hangup.

Wait for the line discipline reference (just like read() or write())
to retrieve the "current" line discipline id.

Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
[bwh: Backported to 2.6.32: adjust filename]
Signed-off-by: Ben Hutchings &lt;ben@decadent.org.uk&gt;
Signed-off-by: Willy Tarreau &lt;w@1wt.eu&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit 5c17c861a357e9458001f021a7afa7aab9937439 upstream.

ioctl(TIOCGETD) retrieves the line discipline id directly from the
ldisc because the line discipline id (c_line) in termios is untrustworthy;
userspace may have set termios via ioctl(TCSETS*) without actually
changing the line discipline via ioctl(TIOCSETD).

However, directly accessing the current ldisc via tty-&gt;ldisc is
unsafe; the ldisc ptr dereferenced may be stale if the line discipline
is changing via ioctl(TIOCSETD) or hangup.

Wait for the line discipline reference (just like read() or write())
to retrieve the "current" line discipline id.

Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
[bwh: Backported to 2.6.32: adjust filename]
Signed-off-by: Ben Hutchings &lt;ben@decadent.org.uk&gt;
Signed-off-by: Willy Tarreau &lt;w@1wt.eu&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>tty: Fix GPF in flush_to_ldisc()</title>
<updated>2016-01-29T21:12:52+00:00</updated>
<author>
<name>Peter Hurley</name>
<email>peter@hurleysoftware.com</email>
</author>
<published>2015-11-27T19:25:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=0dbf4344f37cd793e40f8e91ca19875cf849e7b0'/>
<id>0dbf4344f37cd793e40f8e91ca19875cf849e7b0</id>
<content type='text'>
commit 9ce119f318ba1a07c29149301f1544b6c4bea52a upstream.

A line discipline which does not define a receive_buf() method can
can cause a GPF if data is ever received [1]. Oddly, this was known
to the author of n_tracesink in 2011, but never fixed.

[1] GPF report
    BUG: unable to handle kernel NULL pointer dereference at           (null)
    IP: [&lt;          (null)&gt;]           (null)
    PGD 3752d067 PUD 37a7b067 PMD 0
    Oops: 0010 [#1] SMP KASAN
    Modules linked in:
    CPU: 2 PID: 148 Comm: kworker/u10:2 Not tainted 4.4.0-rc2+ #51
    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
    Workqueue: events_unbound flush_to_ldisc
    task: ffff88006da94440 ti: ffff88006db60000 task.ti: ffff88006db60000
    RIP: 0010:[&lt;0000000000000000&gt;]  [&lt;          (null)&gt;]           (null)
    RSP: 0018:ffff88006db67b50  EFLAGS: 00010246
    RAX: 0000000000000102 RBX: ffff88003ab32f88 RCX: 0000000000000102
    RDX: 0000000000000000 RSI: ffff88003ab330a6 RDI: ffff88003aabd388
    RBP: ffff88006db67c48 R08: ffff88003ab32f9c R09: ffff88003ab31fb0
    R10: ffff88003ab32fa8 R11: 0000000000000000 R12: dffffc0000000000
    R13: ffff88006db67c20 R14: ffffffff863df820 R15: ffff88003ab31fb8
    FS:  0000000000000000(0000) GS:ffff88006dc00000(0000) knlGS:0000000000000000
    CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
    CR2: 0000000000000000 CR3: 0000000037938000 CR4: 00000000000006e0
    Stack:
     ffffffff829f46f1 ffff88006da94bf8 ffff88006da94bf8 0000000000000000
     ffff88003ab31fb0 ffff88003aabd438 ffff88003ab31ff8 ffff88006430fd90
     ffff88003ab32f9c ffffed0007557a87 1ffff1000db6cf78 ffff88003ab32078
    Call Trace:
     [&lt;ffffffff8127cf91&gt;] process_one_work+0x8f1/0x17a0 kernel/workqueue.c:2030
     [&lt;ffffffff8127df14&gt;] worker_thread+0xd4/0x1180 kernel/workqueue.c:2162
     [&lt;ffffffff8128faaf&gt;] kthread+0x1cf/0x270 drivers/block/aoe/aoecmd.c:1302
     [&lt;ffffffff852a7c2f&gt;] ret_from_fork+0x3f/0x70 arch/x86/entry/entry_64.S:468
    Code:  Bad RIP value.
    RIP  [&lt;          (null)&gt;]           (null)
     RSP &lt;ffff88006db67b50&gt;
    CR2: 0000000000000000
    ---[ end trace a587f8947e54d6ea ]---

Reported-by: Dmitry Vyukov &lt;dvyukov@google.com&gt;
Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings &lt;ben@decadent.org.uk&gt;
(cherry picked from commit b23324ffa8ef8cc96865db76db938905d61d949a)
[wt: applied to drivers/char/tty_buffer.c instead]
Signed-off-by: Willy Tarreau &lt;w@1wt.eu&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit 9ce119f318ba1a07c29149301f1544b6c4bea52a upstream.

A line discipline which does not define a receive_buf() method can
can cause a GPF if data is ever received [1]. Oddly, this was known
to the author of n_tracesink in 2011, but never fixed.

[1] GPF report
    BUG: unable to handle kernel NULL pointer dereference at           (null)
    IP: [&lt;          (null)&gt;]           (null)
    PGD 3752d067 PUD 37a7b067 PMD 0
    Oops: 0010 [#1] SMP KASAN
    Modules linked in:
    CPU: 2 PID: 148 Comm: kworker/u10:2 Not tainted 4.4.0-rc2+ #51
    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
    Workqueue: events_unbound flush_to_ldisc
    task: ffff88006da94440 ti: ffff88006db60000 task.ti: ffff88006db60000
    RIP: 0010:[&lt;0000000000000000&gt;]  [&lt;          (null)&gt;]           (null)
    RSP: 0018:ffff88006db67b50  EFLAGS: 00010246
    RAX: 0000000000000102 RBX: ffff88003ab32f88 RCX: 0000000000000102
    RDX: 0000000000000000 RSI: ffff88003ab330a6 RDI: ffff88003aabd388
    RBP: ffff88006db67c48 R08: ffff88003ab32f9c R09: ffff88003ab31fb0
    R10: ffff88003ab32fa8 R11: 0000000000000000 R12: dffffc0000000000
    R13: ffff88006db67c20 R14: ffffffff863df820 R15: ffff88003ab31fb8
    FS:  0000000000000000(0000) GS:ffff88006dc00000(0000) knlGS:0000000000000000
    CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
    CR2: 0000000000000000 CR3: 0000000037938000 CR4: 00000000000006e0
    Stack:
     ffffffff829f46f1 ffff88006da94bf8 ffff88006da94bf8 0000000000000000
     ffff88003ab31fb0 ffff88003aabd438 ffff88003ab31ff8 ffff88006430fd90
     ffff88003ab32f9c ffffed0007557a87 1ffff1000db6cf78 ffff88003ab32078
    Call Trace:
     [&lt;ffffffff8127cf91&gt;] process_one_work+0x8f1/0x17a0 kernel/workqueue.c:2030
     [&lt;ffffffff8127df14&gt;] worker_thread+0xd4/0x1180 kernel/workqueue.c:2162
     [&lt;ffffffff8128faaf&gt;] kthread+0x1cf/0x270 drivers/block/aoe/aoecmd.c:1302
     [&lt;ffffffff852a7c2f&gt;] ret_from_fork+0x3f/0x70 arch/x86/entry/entry_64.S:468
    Code:  Bad RIP value.
    RIP  [&lt;          (null)&gt;]           (null)
     RSP &lt;ffff88006db67b50&gt;
    CR2: 0000000000000000
    ---[ end trace a587f8947e54d6ea ]---

Reported-by: Dmitry Vyukov &lt;dvyukov@google.com&gt;
Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings &lt;ben@decadent.org.uk&gt;
(cherry picked from commit b23324ffa8ef8cc96865db76db938905d61d949a)
[wt: applied to drivers/char/tty_buffer.c instead]
Signed-off-by: Willy Tarreau &lt;w@1wt.eu&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>ipmi: move timer init to before irq is setup</title>
<updated>2016-01-29T21:12:48+00:00</updated>
<author>
<name>Jan Stancek</name>
<email>jstancek@redhat.com</email>
</author>
<published>2015-12-08T18:57:51+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=ac5da7cfac88c0626165ec822f1bdde0d2752a96'/>
<id>ac5da7cfac88c0626165ec822f1bdde0d2752a96</id>
<content type='text'>
commit 27f972d3e00b50639deb4cc1392afaeb08d3cecc upstream.

We encountered a panic on boot in ipmi_si on a dell per320 due to an
uninitialized timer as follows.

static int smi_start_processing(void       *send_info,
                                ipmi_smi_t intf)
{
        /* Try to claim any interrupts. */
        if (new_smi-&gt;irq_setup)
                new_smi-&gt;irq_setup(new_smi);

 --&gt; IRQ arrives here and irq handler tries to modify uninitialized timer

    which triggers BUG_ON(!timer-&gt;function) in __mod_timer().

 Call Trace:
   &lt;IRQ&gt;
   [&lt;ffffffffa0532617&gt;] start_new_msg+0x47/0x80 [ipmi_si]
   [&lt;ffffffffa053269e&gt;] start_check_enables+0x4e/0x60 [ipmi_si]
   [&lt;ffffffffa0532bd8&gt;] smi_event_handler+0x1e8/0x640 [ipmi_si]
   [&lt;ffffffff810f5584&gt;] ? __rcu_process_callbacks+0x54/0x350
   [&lt;ffffffffa053327c&gt;] si_irq_handler+0x3c/0x60 [ipmi_si]
   [&lt;ffffffff810efaf0&gt;] handle_IRQ_event+0x60/0x170
   [&lt;ffffffff810f245e&gt;] handle_edge_irq+0xde/0x180
   [&lt;ffffffff8100fc59&gt;] handle_irq+0x49/0xa0
   [&lt;ffffffff8154643c&gt;] do_IRQ+0x6c/0xf0
   [&lt;ffffffff8100ba53&gt;] ret_from_intr+0x0/0x11

        /* Set up the timer that drives the interface. */
        setup_timer(&amp;new_smi-&gt;si_timer, smi_timeout, (long)new_smi);

The following patch fixes the problem.

To: Openipmi-developer@lists.sourceforge.net
To: Corey Minyard &lt;minyard@acm.org&gt;
CC: linux-kernel@vger.kernel.org

Signed-off-by: Jan Stancek &lt;jstancek@redhat.com&gt;
Signed-off-by: Tony Camuso &lt;tcamuso@redhat.com&gt;
Signed-off-by: Corey Minyard &lt;cminyard@mvista.com&gt;
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings &lt;ben@decadent.org.uk&gt;
(cherry picked from commit 207ffa8cbcf6e780d862316a94c95a7e70d1e72e)
Signed-off-by: Willy Tarreau &lt;w@1wt.eu&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit 27f972d3e00b50639deb4cc1392afaeb08d3cecc upstream.

We encountered a panic on boot in ipmi_si on a dell per320 due to an
uninitialized timer as follows.

static int smi_start_processing(void       *send_info,
                                ipmi_smi_t intf)
{
        /* Try to claim any interrupts. */
        if (new_smi-&gt;irq_setup)
                new_smi-&gt;irq_setup(new_smi);

 --&gt; IRQ arrives here and irq handler tries to modify uninitialized timer

    which triggers BUG_ON(!timer-&gt;function) in __mod_timer().

 Call Trace:
   &lt;IRQ&gt;
   [&lt;ffffffffa0532617&gt;] start_new_msg+0x47/0x80 [ipmi_si]
   [&lt;ffffffffa053269e&gt;] start_check_enables+0x4e/0x60 [ipmi_si]
   [&lt;ffffffffa0532bd8&gt;] smi_event_handler+0x1e8/0x640 [ipmi_si]
   [&lt;ffffffff810f5584&gt;] ? __rcu_process_callbacks+0x54/0x350
   [&lt;ffffffffa053327c&gt;] si_irq_handler+0x3c/0x60 [ipmi_si]
   [&lt;ffffffff810efaf0&gt;] handle_IRQ_event+0x60/0x170
   [&lt;ffffffff810f245e&gt;] handle_edge_irq+0xde/0x180
   [&lt;ffffffff8100fc59&gt;] handle_irq+0x49/0xa0
   [&lt;ffffffff8154643c&gt;] do_IRQ+0x6c/0xf0
   [&lt;ffffffff8100ba53&gt;] ret_from_intr+0x0/0x11

        /* Set up the timer that drives the interface. */
        setup_timer(&amp;new_smi-&gt;si_timer, smi_timeout, (long)new_smi);

The following patch fixes the problem.

To: Openipmi-developer@lists.sourceforge.net
To: Corey Minyard &lt;minyard@acm.org&gt;
CC: linux-kernel@vger.kernel.org

Signed-off-by: Jan Stancek &lt;jstancek@redhat.com&gt;
Signed-off-by: Tony Camuso &lt;tcamuso@redhat.com&gt;
Signed-off-by: Corey Minyard &lt;cminyard@mvista.com&gt;
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings &lt;ben@decadent.org.uk&gt;
(cherry picked from commit 207ffa8cbcf6e780d862316a94c95a7e70d1e72e)
Signed-off-by: Willy Tarreau &lt;w@1wt.eu&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>tty: fix stall caused by missing memory barrier in drivers/tty/n_tty.c</title>
<updated>2015-12-05T23:49:15+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.tavy.me/linux-stable.git/commit/?id=5cd89060d93d4dc0a782e12aceb3fd8897053a4a'/>
<id>5cd89060d93d4dc0a782e12aceb3fd8897053a4a</id>
<content type='text'>
commit e81107d4c6bd098878af9796b24edc8d4a9524fd upstream.

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;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
[bwh: Backported to 3.2:
 - Use wake_up_interruptible(), not wake_up_interruptible_poll()
 - There are only two spurious uses of waitqueue_active() to remove]
Signed-off-by: Ben Hutchings &lt;ben@decadent.org.uk&gt;
(cherry picked from commit 80910ccdd3ee35e4131df38bc73b86ee60abdf0b)
[wt: file is drivers/char/n_tty.c in 2.6.32]
Signed-off-by: Willy Tarreau &lt;w@1wt.eu&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit e81107d4c6bd098878af9796b24edc8d4a9524fd upstream.

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;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
[bwh: Backported to 3.2:
 - Use wake_up_interruptible(), not wake_up_interruptible_poll()
 - There are only two spurious uses of waitqueue_active() to remove]
Signed-off-by: Ben Hutchings &lt;ben@decadent.org.uk&gt;
(cherry picked from commit 80910ccdd3ee35e4131df38bc73b86ee60abdf0b)
[wt: file is drivers/char/n_tty.c in 2.6.32]
Signed-off-by: Willy Tarreau &lt;w@1wt.eu&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>TTY: drop driver reference in tty_open fail path</title>
<updated>2015-09-18T11:51:52+00:00</updated>
<author>
<name>Jiri Slaby</name>
<email>jslaby@suse.cz</email>
</author>
<published>2011-10-12T09:32:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=d447af56f50bdcb4d5ca378ed6b2d48fb0b973ac'/>
<id>d447af56f50bdcb4d5ca378ed6b2d48fb0b973ac</id>
<content type='text'>
commit c290f8358acaeffd8e0c551ddcc24d1206143376 upstream.

When tty_driver_lookup_tty fails in tty_open, we forget to drop a
reference to the tty driver. This was added by commit 4a2b5fddd5 (Move
tty lookup/reopen to caller).

Fix that by adding tty_driver_kref_put to the fail path.

I will refactor the code later. This is for the ease of backporting to
stable.

Introduced-in: v2.6.28-rc2
Signed-off-by: Jiri Slaby &lt;jslaby@suse.cz&gt;
Cc: Alan Cox &lt;alan@lxorguk.ukuu.org.uk&gt;
Acked-by: Sukadev Bhattiprolu &lt;sukadev@linux.vnet.ibm.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@suse.de&gt;
[bwh: Backported to 2.6.32: adjust filename]
Signed-off-by: Ben Hutchings &lt;ben@decadent.org.uk&gt;

CVE-2011-5321

Signed-off-by: Willy Tarreau &lt;w@1wt.eu&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit c290f8358acaeffd8e0c551ddcc24d1206143376 upstream.

When tty_driver_lookup_tty fails in tty_open, we forget to drop a
reference to the tty driver. This was added by commit 4a2b5fddd5 (Move
tty lookup/reopen to caller).

Fix that by adding tty_driver_kref_put to the fail path.

I will refactor the code later. This is for the ease of backporting to
stable.

Introduced-in: v2.6.28-rc2
Signed-off-by: Jiri Slaby &lt;jslaby@suse.cz&gt;
Cc: Alan Cox &lt;alan@lxorguk.ukuu.org.uk&gt;
Acked-by: Sukadev Bhattiprolu &lt;sukadev@linux.vnet.ibm.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@suse.de&gt;
[bwh: Backported to 2.6.32: adjust filename]
Signed-off-by: Ben Hutchings &lt;ben@decadent.org.uk&gt;

CVE-2011-5321

Signed-off-by: Willy Tarreau &lt;w@1wt.eu&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>tty: Fix high cpu load if tty is unreleaseable</title>
<updated>2014-11-23T09:55:47+00:00</updated>
<author>
<name>Peter Hurley</name>
<email>peter@hurleysoftware.com</email>
</author>
<published>2014-10-16T17:51:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=26967a02542d7e0673f82bc1b71e467f37e0f858'/>
<id>26967a02542d7e0673f82bc1b71e467f37e0f858</id>
<content type='text'>
Kernel oops can cause the tty to be unreleaseable (for example, if
n_tty_read() crashes while on the read_wait queue). This will cause
tty_release() to endlessly loop without sleeping.

Use a killable sleep timeout which grows by 2n+1 jiffies over the interval
[0, 120 secs.) and then jumps to forever (but still killable).

NB: killable just allows for the task to be rewoken manually, not
to be terminated.

Cc: &lt;stable@vger.kernel.org&gt;
Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
(cherry picked from commit 37b164578826406a173ca7c20d9ba7430134d23e)
Signed-off-by: Willy Tarreau &lt;w@1wt.eu&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Kernel oops can cause the tty to be unreleaseable (for example, if
n_tty_read() crashes while on the read_wait queue). This will cause
tty_release() to endlessly loop without sleeping.

Use a killable sleep timeout which grows by 2n+1 jiffies over the interval
[0, 120 secs.) and then jumps to forever (but still killable).

NB: killable just allows for the task to be rewoken manually, not
to be terminated.

Cc: &lt;stable@vger.kernel.org&gt;
Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
(cherry picked from commit 37b164578826406a173ca7c20d9ba7430134d23e)
Signed-off-by: Willy Tarreau &lt;w@1wt.eu&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>n_tty: Fix n_tty_write crash when echoing in raw mode</title>
<updated>2014-05-19T05:54:29+00:00</updated>
<author>
<name>Peter Hurley</name>
<email>peter@hurleysoftware.com</email>
</author>
<published>2014-05-03T12:04:59+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=a14cc8a6f5bc2e3c491edc92c07e17ba2f94f1d0'/>
<id>a14cc8a6f5bc2e3c491edc92c07e17ba2f94f1d0</id>
<content type='text'>
The tty atomic_write_lock does not provide an exclusion guarantee for
the tty driver if the termios settings are LECHO &amp; !OPOST.  And since
it is unexpected and not allowed to call TTY buffer helpers like
tty_insert_flip_string concurrently, this may lead to crashes when
concurrect writers call pty_write. In that case the following two
writers:
* the ECHOing from a workqueue and
* pty_write from the process
race and can overflow the corresponding TTY buffer like follows.

If we look into tty_insert_flip_string_fixed_flag, there is:
  int space = __tty_buffer_request_room(port, goal, flags);
  struct tty_buffer *tb = port-&gt;buf.tail;
  ...
  memcpy(char_buf_ptr(tb, tb-&gt;used), chars, space);
  ...
  tb-&gt;used += space;

so the race of the two can result in something like this:
              A                                B
__tty_buffer_request_room
                                  __tty_buffer_request_room
memcpy(buf(tb-&gt;used), ...)
tb-&gt;used += space;
                                  memcpy(buf(tb-&gt;used), ...) -&gt;BOOM

B's memcpy is past the tty_buffer due to the previous A's tb-&gt;used
increment.

Since the N_TTY line discipline input processing can output
concurrently with a tty write, obtain the N_TTY ldisc output_lock to
serialize echo output with normal tty writes.  This ensures the tty
buffer helper tty_insert_flip_string is not called concurrently and
everything is fine.

Note that this is nicely reproducible by an ordinary user using
forkpty and some setup around that (raw termios + ECHO). And it is
present in kernels at least after commit
d945cb9cce20ac7143c2de8d88b187f62db99bdc (pty: Rework the pty layer to
use the normal buffering logic) in 2.6.31-rc3.

js: add more info to the commit log
js: switch to bool
js: lock unconditionally
js: lock only the tty-&gt;ops-&gt;write call

References: CVE-2014-0196
Reported-and-tested-by: Jiri Slaby &lt;jslaby@suse.cz&gt;
Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Jiri Slaby &lt;jslaby@suse.cz&gt;
Cc: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
Cc: Alan Cox &lt;alan@lxorguk.ukuu.org.uk&gt;
Cc: &lt;stable@vger.kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
(cherry picked from commit 4291086b1f081b869c6d79e5b7441633dc3ace00)
[wt: 2.6.32 has no n_tty_data, so output_lock is in tty, not tty-&gt;disc_data]
Signed-off-by: Willy Tarreau &lt;w@1wt.eu&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The tty atomic_write_lock does not provide an exclusion guarantee for
the tty driver if the termios settings are LECHO &amp; !OPOST.  And since
it is unexpected and not allowed to call TTY buffer helpers like
tty_insert_flip_string concurrently, this may lead to crashes when
concurrect writers call pty_write. In that case the following two
writers:
* the ECHOing from a workqueue and
* pty_write from the process
race and can overflow the corresponding TTY buffer like follows.

If we look into tty_insert_flip_string_fixed_flag, there is:
  int space = __tty_buffer_request_room(port, goal, flags);
  struct tty_buffer *tb = port-&gt;buf.tail;
  ...
  memcpy(char_buf_ptr(tb, tb-&gt;used), chars, space);
  ...
  tb-&gt;used += space;

so the race of the two can result in something like this:
              A                                B
__tty_buffer_request_room
                                  __tty_buffer_request_room
memcpy(buf(tb-&gt;used), ...)
tb-&gt;used += space;
                                  memcpy(buf(tb-&gt;used), ...) -&gt;BOOM

B's memcpy is past the tty_buffer due to the previous A's tb-&gt;used
increment.

Since the N_TTY line discipline input processing can output
concurrently with a tty write, obtain the N_TTY ldisc output_lock to
serialize echo output with normal tty writes.  This ensures the tty
buffer helper tty_insert_flip_string is not called concurrently and
everything is fine.

Note that this is nicely reproducible by an ordinary user using
forkpty and some setup around that (raw termios + ECHO). And it is
present in kernels at least after commit
d945cb9cce20ac7143c2de8d88b187f62db99bdc (pty: Rework the pty layer to
use the normal buffering logic) in 2.6.31-rc3.

js: add more info to the commit log
js: switch to bool
js: lock unconditionally
js: lock only the tty-&gt;ops-&gt;write call

References: CVE-2014-0196
Reported-and-tested-by: Jiri Slaby &lt;jslaby@suse.cz&gt;
Signed-off-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Jiri Slaby &lt;jslaby@suse.cz&gt;
Cc: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
Cc: Alan Cox &lt;alan@lxorguk.ukuu.org.uk&gt;
Cc: &lt;stable@vger.kernel.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
(cherry picked from commit 4291086b1f081b869c6d79e5b7441633dc3ace00)
[wt: 2.6.32 has no n_tty_data, so output_lock is in tty, not tty-&gt;disc_data]
Signed-off-by: Willy Tarreau &lt;w@1wt.eu&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>drivers/char/ipmi: memcpy, need additional 2 bytes to avoid memory overflow</title>
<updated>2013-06-10T09:42:41+00:00</updated>
<author>
<name>Chen Gang</name>
<email>gang.chen@asianux.com</email>
</author>
<published>2013-05-16T19:04:25+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=9eeeda586fae4eeb7af6a52a6cbb66051624bc48'/>
<id>9eeeda586fae4eeb7af6a52a6cbb66051624bc48</id>
<content type='text'>
commit a5f2b3d6a738e7d4180012fe7b541172f8c8dcea upstream.

When calling memcpy, read_data and write_data need additional 2 bytes.

  write_data:
    for checking:  "if (size &gt; IPMI_MAX_MSG_LENGTH)"
    for operating: "memcpy(bt-&gt;write_data + 3, data + 1, size - 1)"

  read_data:
    for checking:  "if (msg_len &lt; 3 || msg_len &gt; IPMI_MAX_MSG_LENGTH)"
    for operating: "memcpy(data + 2, bt-&gt;read_data + 4, msg_len - 2)"

Signed-off-by: Chen Gang &lt;gang.chen@asianux.com&gt;
Signed-off-by: Corey Minyard &lt;cminyard@mvista.com&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
Signed-off-by: Willy Tarreau &lt;w@1wt.eu&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit a5f2b3d6a738e7d4180012fe7b541172f8c8dcea upstream.

When calling memcpy, read_data and write_data need additional 2 bytes.

  write_data:
    for checking:  "if (size &gt; IPMI_MAX_MSG_LENGTH)"
    for operating: "memcpy(bt-&gt;write_data + 3, data + 1, size - 1)"

  read_data:
    for checking:  "if (msg_len &lt; 3 || msg_len &gt; IPMI_MAX_MSG_LENGTH)"
    for operating: "memcpy(data + 2, bt-&gt;read_data + 4, msg_len - 2)"

Signed-off-by: Chen Gang &lt;gang.chen@asianux.com&gt;
Signed-off-by: Corey Minyard &lt;cminyard@mvista.com&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
Signed-off-by: Willy Tarreau &lt;w@1wt.eu&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>random: Add comment to random_initialize()</title>
<updated>2012-10-07T21:41:21+00:00</updated>
<author>
<name>Tony Luck</name>
<email>tony.luck@intel.com</email>
</author>
<published>2012-07-23T16:47:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=a76be4858901fd9fd0fb8f594f660d1037cb03d8'/>
<id>a76be4858901fd9fd0fb8f594f660d1037cb03d8</id>
<content type='text'>
commit cbc96b7594b5691d61eba2db8b2ea723645be9ca upstream.

Many platforms have per-machine instance data (serial numbers,
asset tags, etc.) squirreled away in areas that are accessed
during early system bringup. Mixing this data into the random
pools has a very high value in providing better random data,
so we should allow (and even encourage) architecture code to
call add_device_randomness() from the setup_arch() paths.

However, this limits our options for internal structure of
the random driver since random_initialize() is not called
until long after setup_arch().

Add a big fat comment to rand_initialize() spelling out
this requirement.

Suggested-by: Theodore Ts'o &lt;tytso@mit.edu&gt;
Signed-off-by: Tony Luck &lt;tony.luck@intel.com&gt;
Signed-off-by: Theodore Ts'o &lt;tytso@mit.edu&gt;
Signed-off-by: Paul Gortmaker &lt;paul.gortmaker@windriver.com&gt;
Signed-off-by: Willy Tarreau &lt;w@1wt.eu&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit cbc96b7594b5691d61eba2db8b2ea723645be9ca upstream.

Many platforms have per-machine instance data (serial numbers,
asset tags, etc.) squirreled away in areas that are accessed
during early system bringup. Mixing this data into the random
pools has a very high value in providing better random data,
so we should allow (and even encourage) architecture code to
call add_device_randomness() from the setup_arch() paths.

However, this limits our options for internal structure of
the random driver since random_initialize() is not called
until long after setup_arch().

Add a big fat comment to rand_initialize() spelling out
this requirement.

Suggested-by: Theodore Ts'o &lt;tytso@mit.edu&gt;
Signed-off-by: Tony Luck &lt;tony.luck@intel.com&gt;
Signed-off-by: Theodore Ts'o &lt;tytso@mit.edu&gt;
Signed-off-by: Paul Gortmaker &lt;paul.gortmaker@windriver.com&gt;
Signed-off-by: Willy Tarreau &lt;w@1wt.eu&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>random: remove rand_initialize_irq()</title>
<updated>2012-10-07T21:41:21+00:00</updated>
<author>
<name>Theodore Ts'o</name>
<email>tytso@mit.edu</email>
</author>
<published>2012-07-15T00:27:52+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=fe1f4c7d2602bda2dddb13fd34e9678514478e12'/>
<id>fe1f4c7d2602bda2dddb13fd34e9678514478e12</id>
<content type='text'>
commit c5857ccf293968348e5eb4ebedc68074de3dcda6 upstream.

With the new interrupt sampling system, we are no longer using the
timer_rand_state structure in the irq descriptor, so we can stop
initializing it now.

[ Merged in fixes from Sedat to find some last missing references to
  rand_initialize_irq() ]

Signed-off-by: "Theodore Ts'o" &lt;tytso@mit.edu&gt;
Signed-off-by: Sedat Dilek &lt;sedat.dilek@gmail.com&gt;
[PG: in .34 the irqdesc.h content is in irq.h instead.]
Signed-off-by: Paul Gortmaker &lt;paul.gortmaker@windriver.com&gt;
Signed-off-by: Willy Tarreau &lt;w@1wt.eu&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit c5857ccf293968348e5eb4ebedc68074de3dcda6 upstream.

With the new interrupt sampling system, we are no longer using the
timer_rand_state structure in the irq descriptor, so we can stop
initializing it now.

[ Merged in fixes from Sedat to find some last missing references to
  rand_initialize_irq() ]

Signed-off-by: "Theodore Ts'o" &lt;tytso@mit.edu&gt;
Signed-off-by: Sedat Dilek &lt;sedat.dilek@gmail.com&gt;
[PG: in .34 the irqdesc.h content is in irq.h instead.]
Signed-off-by: Paul Gortmaker &lt;paul.gortmaker@windriver.com&gt;
Signed-off-by: Willy Tarreau &lt;w@1wt.eu&gt;
</pre>
</div>
</content>
</entry>
</feed>
