lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-Id: <20160123141223.285379115@1wt.eu>
Date:	Sat, 23 Jan 2016 15:12:51 +0100
From:	Willy Tarreau <w@....eu>
To:	linux-kernel@...r.kernel.org, stable@...r.kernel.org
Cc:	Dmitry Vyukov <dvyukov@...gle.com>,
	Peter Hurley <peter@...leysoftware.com>,
	Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
	Ben Hutchings <ben@...adent.org.uk>, Willy Tarreau <w@....eu>
Subject: [PATCH 2.6.32 30/42] tty: Fix GPF in flush_to_ldisc()

2.6.32-longterm review patch.  If anyone has any objections, please let me know.

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

From: Peter Hurley <peter@...leysoftware.com>

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: [<          (null)>]           (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:[<0000000000000000>]  [<          (null)>]           (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:
     [<ffffffff8127cf91>] process_one_work+0x8f1/0x17a0 kernel/workqueue.c:2030
     [<ffffffff8127df14>] worker_thread+0xd4/0x1180 kernel/workqueue.c:2162
     [<ffffffff8128faaf>] kthread+0x1cf/0x270 drivers/block/aoe/aoecmd.c:1302
     [<ffffffff852a7c2f>] ret_from_fork+0x3f/0x70 arch/x86/entry/entry_64.S:468
    Code:  Bad RIP value.
    RIP  [<          (null)>]           (null)
     RSP <ffff88006db67b50>
    CR2: 0000000000000000
    ---[ end trace a587f8947e54d6ea ]---

Reported-by: Dmitry Vyukov <dvyukov@...gle.com>
Signed-off-by: Peter Hurley <peter@...leysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@...adent.org.uk>
(cherry picked from commit b23324ffa8ef8cc96865db76db938905d61d949a)
[wt: applied to drivers/char/tty_buffer.c instead]
Signed-off-by: Willy Tarreau <w@....eu>
---
 drivers/char/tty_buffer.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/char/tty_buffer.c b/drivers/char/tty_buffer.c
index 9605ee5..fbc5824 100644
--- a/drivers/char/tty_buffer.c
+++ b/drivers/char/tty_buffer.c
@@ -450,10 +450,12 @@ static void flush_to_ldisc(struct work_struct *work)
 			char_buf = head->char_buf_ptr + head->read;
 			flag_buf = head->flag_buf_ptr + head->read;
 			head->read += count;
-			spin_unlock_irqrestore(&tty->buf.lock, flags);
-			disc->ops->receive_buf(tty, char_buf,
+			if (disc->ops->receive_buf) {
+				spin_unlock_irqrestore(&tty->buf.lock, flags);
+				disc->ops->receive_buf(tty, char_buf,
 							flag_buf, count);
-			spin_lock_irqsave(&tty->buf.lock, flags);
+				spin_lock_irqsave(&tty->buf.lock, flags);
+			}
 		}
 		clear_bit(TTY_FLUSHING, &tty->flags);
 	}
-- 
1.7.12.2.21.g234cd45.dirty



Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ