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
prev parent 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.