Re: BUG: GPF in non-whitelisted uaccess (non-canonical address?)
From: David Herrmann <hidden>
Date: 2018-11-14 12:21:09
Also in:
lkml
Hey On Wed, Nov 14, 2018 at 1:25 AM syzbot [off-list ref] wrote:
syzbot has found a reproducer for the following crash on: HEAD commit: ccda4af0f4b9 Linux 4.20-rc2 git tree: upstream console output: https://syzkaller.appspot.com/x/log.txt?x=13b4e77b400000 kernel config: https://syzkaller.appspot.com/x/.config?x=4a0a89f12ca9b0f5 dashboard link: https://syzkaller.appspot.com/bug?extid=72473edc9bf4eb1c6556 compiler: gcc (GCC) 8.0.1 20180413 (experimental) syz repro: https://syzkaller.appspot.com/x/repro.syz?x=1646a225400000 C reproducer: https://syzkaller.appspot.com/x/repro.c?x=108a6533400000 IMPORTANT: if you fix the bug, please add the following tag to the commit: Reported-by: syzbot+72473edc9bf4eb1c6556@syzkaller.appspotmail.com
[...]
BUG: GPF in non-whitelisted uaccess (non-canonical address?)
This uses sendpage(2) to feed data from a file into a uhid chardev. The default behavior of the kernel is to create a temporary pipe, then splice from the file into the pipe, and then splice again from the pipe into uhid. The kernel provides default implementations for splicing between files and any other file. The default implementation of `.splice_write()` uses kmap() to map the page from the pipe and then uses the __kernel_write() (which uses .f_op->write()) to push the data into the target file. The problem is, __kernel_write() sets the address-space to KERNEL_DS `set_fs(get_ds())`, thus granting the UHID request access to kernel memory. I see several ways to fix that, the most simple solution is to simply prevent splice/sendpage on uhid (by setting f_op.splice_write to a dummy). Alternatively, we can implement a proper splice helper that takes the page directly, rather than through the __kernel_write() default implementation. Thanks David