Re: NULL-ptr deref in irqfd_update (via KVM)
From: Robert ÅwiÄcki
Date: Fri Feb 19 2016 - 21:11:23 EST
Hm.. I think now it's the same as
https://groups.google.com/forum/#!topic/syzkaller/Rg4Y2Z6HbHI - just
with a bit different stacktrace, and simpler testcase.
2016-02-20 3:07 GMT+01:00 Robert ÅwiÄcki <robert@xxxxxxxxxxx>:
> Works under both AMD and Intel
>
> [7]kdb> summary
> sysname Linux
> release 4.5.0-rc4
> version #1 SMP PREEMPT Tue Feb 16 04:24:23 CET 2016
> machine x86_64
> nodename jag-l2
> domainname (none)
> ccversion CCVERSION
> date 2016-02-20 01:57:30 tz_minuteswest 0
> uptime 00:06
> load avg 0.35 0.14 0.04
>
> MemTotal: 16409820 kB
> MemFree: 16054940 kB
> Buffers: 37564 kB
>
>
> [ 70.223390] BUG: unable to handle kernel NULL pointer dereference
> at 0000000000000120
> [ 70.224535] IP: [<ffffffff81009f69>] kvm_irq_map_gsi+0x12/0x5a
> [ 70.225400] PGD bd3ca067 PUD bd0ed067 PMD 0
> [ 70.226018] Oops: 0000 [#1] PREEMPT SMP
>
> Entering kdb (current=0xffff88042a4ae040, pid 4403) on processor 7 Oops: (null)
> due to oops @ 0xffffffff81009f69
> CPU: 7 PID: 4403 Comm: o Not tainted 4.5.0-rc4 #1
> Hardware name: To be filled by O.E.M. To be filled by O.E.M./Crosshair
> V Formula, BIOS 1703 10/17/2012
> task: ffff88042a4ae040 ti: ffff8800bb0ec000 task.ti: ffff8800bb0ec000
> RIP: 0010:[<ffffffff81009f69>] [<ffffffff81009f69>] kvm_irq_map_gsi+0x12/0x5a
> RSP: 0018:ffff8800bb0efc90 EFLAGS: 00010046
> RAX: 0000000000000000 RBX: ffff8804228fc000 RCX: 0000000000000000
> RDX: 0000000000000003 RSI: ffff8800bb0efca0 RDI: ffff8800bb1dc000
> RBP: ffff8800bb0efc90 R08: 0000000000000007 R09: 00000000000000ff
> R10: ffff8800bb0efd70 R11: 0000000000000212 R12: ffff8800bb0efca0
> R13: 0000000000000001 R14: ffff8804228fc000 R15: ffff8800bb1dca50
> FS: 00007f44d4e1b700(0000) GS:ffff88043d5c0000(0000) knlGS:0000000000000000
> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 0000000000000120 CR3: 00000000bb018000 CR4: 00000000000406e0
> Stack:
> ffff8800bb0efd78 ffffffff81008e6d ffff8800bb1dc158 ffff8800bb1dc120
> ffff8800bb0efce0 ffff8800bb1dc101 0000000000000002 ffff8804228fc0a8
> ffff8800bb0efd50 ffffffff81168356 0000000000000000 ffffffff81167aed
> Call Trace:
> [<ffffffff81008e6d>] irqfd_update+0x37/0x78
> [<ffffffff81168356>] ? __synchronize_srcu+0xdf/0x12a
> [<ffffffff81167aed>] ? trace_raw_output_rcu_utilization+0x60/0x60
> [<ffffffff813ca0cd>] ? __this_cpu_preempt_check+0x13/0x15
> [<ffffffff811685f0>] ? __srcu_read_lock+0x43/0x56
> [<ffffffff81009ae1>] kvm_irqfd+0x3f2/0x53f
> [<ffffffff810066a1>] kvm_vm_ioctl+0x2f9/0x65f
> [<ffffffff8115b065>] ? __raw_write_unlock+0x11/0x23
> [<ffffffff81ba6c16>] ? _raw_spin_unlock+0xe/0x10
> [<ffffffff812315dd>] vfs_ioctl+0x18/0x34
> [<ffffffff81231fae>] do_vfs_ioctl+0x493/0x514
> [<ffffffff8108e1f1>] ? __do_page_fault+0x2b0/0x324
> [<ffffffff81232086>] SyS_ioctl+0x57/0x79
> [<ffffffff81ba70b2>] entry_SYSCALL_64_fastpath+0x16/0x71
> Code: 5b 41 5c 41 5d 41 5e 5d c3 55 be c0 80 40 02 48 89 e5 e8 d9 a2
> 20 00 5d c3 0f 1f 44 00 00 55 48 8b 8f 08 2e 00 00 31 c0 48 89 e5 <39>
> 91 20 01 00 00 76 3e 48 63 d2 49 89 f1 48 8b 94 d1 28 01 00
>
> Testcase:
> ===================================
> // autogenerated by syzkaller (http://github.com/google/syzkaller)
> #include <unistd.h>
> #include <sys/syscall.h>
> #include <string.h>
> #include <stdint.h>
> #include <pthread.h>
>
> #ifndef SYS_mmap
> #define SYS_mmap 9
> #endif
> #ifndef SYS_syz_open_dev
> #define SYS_syz_open_dev 1000001
> #endif
> #ifndef SYS_ioctl
> #define SYS_ioctl 16
> #endif
> #ifndef SYS_eventfd
> #define SYS_eventfd 284
> #endif
>
> long r[26];
>
> int main()
> {
> memset(r, -1, sizeof(r));
> r[0] = syscall(SYS_mmap, 0x20000000ul, 0x17000ul, 0x3ul, 0x32ul,
> 0xfffffffffffffffful, 0x0ul);
> memcpy((void*)0x2000c000, "\x2f\x64\x65\x76\x2f\x6b\x76\x6d\x00", 9);
> r[2] =
> syscall(SYS_open, 0x2000c000ul, 0x0ul, 0x400ul, 0, 0, 0);
> r[3] = syscall(SYS_ioctl, r[2], 0xae01ul, 0x0ul, 0, 0, 0);
> r[4] = syscall(SYS_eventfd, 0x5ul, 0, 0, 0, 0, 0);
> *(uint32_t*)0x2000cfef = r[4];
> *(uint32_t*)0x2000cff3 = (uint32_t)0x3;
> *(uint32_t*)0x2000cff7 = (uint32_t)0x2;
> *(uint32_t*)0x2000cffb = r[4];
> *(uint8_t*)0x2000cfff = (uint8_t)0x0;
> *(uint8_t*)0x2000d000 = (uint8_t)0x0;
> *(uint8_t*)0x2000d001 = (uint8_t)0x0;
> *(uint8_t*)0x2000d002 = (uint8_t)0x0;
> *(uint8_t*)0x2000d003 = (uint8_t)0x0;
> *(uint8_t*)0x2000d004 = (uint8_t)0x0;
> *(uint8_t*)0x2000d005 = (uint8_t)0x0;
> *(uint8_t*)0x2000d006 = (uint8_t)0x0;
> *(uint8_t*)0x2000d007 = (uint8_t)0x0;
> *(uint8_t*)0x2000d008 = (uint8_t)0x0;
> *(uint8_t*)0x2000d009 = (uint8_t)0x0;
> *(uint8_t*)0x2000d00a = (uint8_t)0x0;
> *(uint8_t*)0x2000d00b = (uint8_t)0x0;
> *(uint8_t*)0x2000d00c = (uint8_t)0x0;
> *(uint8_t*)0x2000d00d = (uint8_t)0x0;
> *(uint8_t*)0x2000d00e = (uint8_t)0x0;
> r[25] = syscall(SYS_ioctl, r[3], 0x4020ae76ul, 0x2000cfeful, 0, 0, 0);
> return 0;
> }
> ===================================
>
> From KGDB:
>>>> target remote /dev/ttyUSB0
> Remote debugging using /dev/ttyUSB0
> Ignoring packet error, continuing...
> warning: unrecognized item "timeout" in "qSupported" response
> kvm_irq_map_gsi (kvm=0xffff8800bb1dc000, entries=0xffff8800bb0efca0,
> gsi=3) at arch/x86/kvm/../../../virt/kvm/irqchip.c:43
> 43 if (gsi < irq_rt->nr_rt_entries) {
> âââ Assembly ââââââââ
> 0xffffffff81009f5d kvm_irq_map_gsi+6 mov 0x2e08(%rdi),%rcx
> 0xffffffff81009f64 kvm_irq_map_gsi+13 xor %eax,%eax
> 0xffffffff81009f66 kvm_irq_map_gsi+15 mov %rsp,%rbp
> 0xffffffff81009f69 kvm_irq_map_gsi+18 cmp %edx,0x120(%rcx) <--
> THIS INSN CAUSES GPF
> 0xffffffff81009f6f kvm_irq_map_gsi+24 jbe 0xffffffff81009faf
> <kvm_irq_map_gsi+88>
> 0xffffffff81009f71 kvm_irq_map_gsi+26 movslq %edx,%rdx
> 0xffffffff81009f74 kvm_irq_map_gsi+29 mov %rsi,%r9
> âââ Expressions âââââââ
> âââ History ââââââââââ
> âââ Memory ââââââââââ
> âââ Registers âââââââââ
> rax 0x0000000000000000 rbx 0xffff8804228fc000 rcx
> 0x0000000000000000 rdx 0x0000000000000003
> rsi 0xffff8800bb0efca0 rdi 0xffff8800bb1dc000 rbp
> 0xffff8800bb0efc90 rsp 0xffff8800bb0efc90
> r8 0x0000000000000007 r9 0x00000000000000ff r10
> 0xffff8800bb0efd70 r11 0x0000000000000212
> r12 0xffff8800bb0efca0 r13 0x0000000000000001 r14
> 0xffff8804228fc000 r15 0xffff8800bb1dca50
> rip 0xffffffff81009f69 eflags [ PF ZF RF ] cs
> 0x00000010 ss 0x00000018
> ds 0x00000000 es 0x00000000 fs
> 0x00000000 gs 0x00000000
> âââ Source ââââââââââ
> 38 struct kvm_kernel_irq_routing_entry *e;
> 39 int n = 0;
> 40
> 41 irq_rt = srcu_dereference_check(kvm->irq_routing, &kvm->irq_srcu,
> 42 lockdep_is_held(&kvm->irq_lock));
> 43 if (gsi < irq_rt->nr_rt_entries) { <--- THIS LINE CAUSES GPF
> 44 hlist_for_each_entry(e, &irq_rt->map[gsi], link) {
> 45 entries[n] = *e;
> 46 ++n;
> 47 }
> âââ Stack âââââ
> [0] from 0xffffffff81009f69 in kvm_irq_map_gsi+18 at
> arch/x86/kvm/../../../virt/kvm/irqchip.c:43
> arg kvm = 0xffff8800bb1dc000
> arg entries = 0xffff8800bb0efca0
> arg gsi = 3
> [1] from 0xffffffff81008e6d in irqfd_update+55 at
> arch/x86/kvm/../../../virt/kvm/eventfd.c:251
> arg kvm = <optimized out>
> arg irqfd = 0xffff8804228fc000
> [+]
>
>>>> bt
> #0 kvm_irq_map_gsi (kvm=0xffff8800bb1dc000,
> entries=0xffff8800bb0efca0, gsi=3) at
> arch/x86/kvm/../../../virt/kvm/irqchip.c:43
> #1 0xffffffff81008e6d in irqfd_update (kvm=<optimized out>,
> irqfd=0xffff8804228fc000) at
> arch/x86/kvm/../../../virt/kvm/eventfd.c:251
> #2 0xffffffff81009ae1 in kvm_irqfd_assign (args=<optimized out>,
> kvm=<optimized out>) at arch/x86/kvm/../../../virt/kvm/eventfd.c:389
> #3 kvm_irqfd (kvm=0xffff8800bb1dc000, args=<optimized out>) at
> arch/x86/kvm/../../../virt/kvm/eventfd.c:570
> #4 0xffffffff810066a1 in kvm_vm_ioctl (filp=<optimized out>,
> ioctl=1075883638, arg=536924143) at
> arch/x86/kvm/../../../virt/kvm/kvm_main.c:2792
> #5 0xffffffff812315dd in vfs_ioctl (filp=<optimized out>,
> cmd=<optimized out>, arg=<optimized out>) at fs/ioctl.c:43
> #6 0xffffffff81231fae in do_vfs_ioctl (filp=0xffff8804228c8100,
> fd=<optimized out>, cmd=<optimized out>, arg=536924143) at
> fs/ioctl.c:674
> #7 0xffffffff81232086 in SYSC_ioctl (arg=<optimized out>,
> cmd=<optimized out>, fd=<optimized out>) at fs/ioctl.c:689
> #8 SyS_ioctl (fd=4, cmd=1075883638, arg=536924143) at fs/ioctl.c:680
> #9 0xffffffff81ba70b2 in entry_SYSCALL_64_fastpath () at
> arch/x86/entry/entry_64.S:185
>
> --
> Robert ÅwiÄcki
--
Robert ÅwiÄcki