All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Hurley <peter@hurleysoftware.com>
To: Dmitry Vyukov <dvyukov@google.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Jiri Slaby <jslaby@suse.com>, LKML <linux-kernel@vger.kernel.org>
Cc: syzkaller <syzkaller@googlegroups.com>,
	Kostya Serebryany <kcc@google.com>,
	Alexander Potapenko <glider@google.com>,
	Eric Dumazet <edumazet@google.com>,
	Sasha Levin <sasha.levin@oracle.com>,
	J Freyensee <james_p_freyensee@linux.intel.com>
Subject: Re: GPF in process_one_work (flush_to_ldisc)
Date: Thu, 26 Nov 2015 13:05:15 -0500	[thread overview]
Message-ID: <565749DB.5030109@hurleysoftware.com> (raw)
In-Reply-To: <CACT4Y+YWNx68E0-9No9L09xsXz-aakbsVwNYqn+8d+VcEgxNAQ@mail.gmail.com>

+ James Freyensee (author of N_TRACESINK line discipline)

On 11/26/2015 09:17 AM, Dmitry Vyukov wrote:
> Hello,
> 
> The following program triggers GPF:

Thanks for the report, Dmitry.
Patch attached should fix the GPF.

The GPF happens because the N_TRACESINK line discipline does not
define a receive_buf() method, so the function ptr is NULL.
I audited every ldisc method invocation in case there were other similar
lurking GPFs, but every other method is first checked for NULL.

Thanks again.

Regards,
Peter Hurley


> // autogenerated by syzkaller (http://github.com/google/syzkaller)
> #include <syscall.h>
> #include <string.h>
> #include <stdint.h>
> 
> int main()
> {
>         long r0 = syscall(SYS_mmap, 0x20000000ul, 0x10000ul, 0x3ul,
> 0x32ul, 0xfffffffffffffffful, 0x0ul);
>         long r1 = syscall(SYS_pipe2, 0x20000000ul, 0x80000ul, 0, 0, 0, 0);
>         long r2 = -1;
>         if (r1 != -1)
>                 r2 = *(uint32_t*)0x20000000;
>         long r3 = -1;
>         if (r1 != -1)
>                 r3 = *(uint32_t*)0x20000004;
>         long r6 = syscall(SYS_open, "/dev/ptmx", 0x1ul, 0x0ul, 0, 0, 0);
>         long r10 = syscall(SYS_write, r6, 0x20001000ul, 0x1000ul, 0, 0, 0);
>         *(uint32_t*)0x20003000 = 0x17;
>         long r12 = syscall(SYS_ioctl, r6, 0x5423ul, 0x20003000ul, 0, 0, 0);
>         long r18 = syscall(SYS_mmap, 0x20002000ul, 0x1000ul, 0x3ul,
> 0x32ul, r2, 0x0ul);
>         long r20 = syscall(SYS_mmap, 0x20002000ul, 0x1000ul, 0x3ul,
> 0x32ul, 0xfffffffffffffffful, 0x0ul);
>         *(uint64_t*)0x20002000 = 0x2000225e;
>         *(uint64_t*)0x20002008 = 0x56;
>         *(uint64_t*)0x20002010 = 0x20002bc6;
>         *(uint64_t*)0x20002018 = 0xe7;
>         *(uint64_t*)0x20002020 = 0x20002fd7;
>         *(uint64_t*)0x20002028 = 0x29;
>         *(uint64_t*)0x20002030 = 0x20002f39;
>         *(uint64_t*)0x20002038 = 0xc7;
>         long r33 = syscall(SYS_writev, r3, 0x20002000ul, 0x4ul, 0, 0, 0);
>         long r34 = syscall(SYS_dup2, r2, r6, 0, 0, 0, 0);
>         return 0;
> }
> 
> 
> 
> 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 ]---
> 
> 
> strace output:
> 
> execve("./a.out", ["./a.out"], [/* 14 vars */]) = 0
> brk(0)                                  = 0x1590000
> brk(0x15911c0)                          = 0x15911c0
> arch_prctl(ARCH_SET_FS, 0x1590880)      = 0
> readlink("/proc/self/exe", "/root/a.out", 4096) = 11
> brk(0x15b21c0)                          = 0x15b21c0
> brk(0x15b3000)                          = 0x15b3000
> access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
> mmap(0x20000000, 65536, PROT_READ|PROT_WRITE,
> MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x20000000
> pipe2([3, 4], O_CLOEXEC)                = 0
> open("/dev/ptmx", O_WRONLY)             = 5
> write(5, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
> 4096) = 4096
> ioctl(5, TIOCSETD, [23])                = 0
> mmap(0x20002000, 4096, PROT_READ|PROT_WRITE,
> MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, 3, 0) = 0x20002000
> mmap(0x20002000, 4096, PROT_READ|PROT_WRITE,
> MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x20002000
> writev(4, [{"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
> 86}, {"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
> 231}, {"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
> 41}, {"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
> 199}], 4) = 557
> dup2(3, 5
> 
> at this point VM hangs.
> 
> On commit 6ffeba9607343f15303a399bc402a538800d89d9 (Now 24).
> 

--- >% ---
Subject: [PATCH] tty: Fix GPF in flush_to_ldisc()

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@google.com>
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
---
 drivers/tty/tty_buffer.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c
index 9a479e6..3cd31e0 100644
--- a/drivers/tty/tty_buffer.c
+++ b/drivers/tty/tty_buffer.c
@@ -450,7 +450,7 @@ receive_buf(struct tty_struct *tty, struct tty_buffer *head, int count)
 		count = disc->ops->receive_buf2(tty, p, f, count);
 	else {
 		count = min_t(int, count, tty->receive_room);
-		if (count)
+		if (count && disc->ops->receive_buf)
 			disc->ops->receive_buf(tty, p, f, count);
 	}
 	return count;
-- 
2.6.3



      reply	other threads:[~2015-11-26 18:05 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-26 14:17 GPF in process_one_work (flush_to_ldisc) Dmitry Vyukov
2015-11-26 18:05 ` Peter Hurley [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=565749DB.5030109@hurleysoftware.com \
    --to=peter@hurleysoftware.com \
    --cc=dvyukov@google.com \
    --cc=edumazet@google.com \
    --cc=glider@google.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=james_p_freyensee@linux.intel.com \
    --cc=jslaby@suse.com \
    --cc=kcc@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sasha.levin@oracle.com \
    --cc=syzkaller@googlegroups.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.