From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751794AbcFUNVn (ORCPT ); Tue, 21 Jun 2016 09:21:43 -0400 Received: from mail-lf0-f41.google.com ([209.85.215.41]:36733 "EHLO mail-lf0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750731AbcFUNVJ (ORCPT ); Tue, 21 Jun 2016 09:21:09 -0400 MIME-Version: 1.0 From: Dmitry Vyukov Date: Tue, 21 Jun 2016 15:19:53 +0200 Message-ID: Subject: kvm: use-after-free in kvm_irqfd_release To: Paolo Bonzini , mtosatti@redhat.com, yoshikawa_takuya_b1@lab.ntt.co.jp, guangrong.xiao@linux.intel.com, Steve Rutherford , rkrcmar@redhat.com, KVM list , LKML Cc: syzkaller , Alexander Potapenko , Kostya Serebryany , Sasha Levin Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hello, The following program triggers use-after-free in kvm_irqfd_release: BUG: KASAN: use-after-free in do_raw_spin_lock+0x281/0x2b0 at addr ffff880060888c64 Read of size 4 by task a.out/7084 page:ffffea0001822200 count:0 mapcount:-127 mapping: (null) index:0x0 flags: 0x4fffe0000000000() page dumped because: kasan: bad access detected CPU: 2 PID: 7084 Comm: a.out Tainted: G D 4.7.0-rc4+ #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 ffffffff880b58e0 ffff880060b77b78 ffffffff82cc62cf ffffffff60b77c08 fffffbfff1016b1c ffff880060b77c08 ffff880060888c64 ffff880060888c98 ffff88003ad2d6a8 ffff880060888c60 ffff880060b77bf8 ffffffff817bdfb2 Call Trace: [] __asan_report_load4_noabort+0x3e/0x40 mm/kasan/report.c:318 [< inline >] debug_spin_lock_before kernel/locking/spinlock_debug.c:83 [] do_raw_spin_lock+0x281/0x2b0 kernel/locking/spinlock_debug.c:135 [< inline >] __raw_spin_lock_irq include/linux/spinlock_api_smp.h:131 [] _raw_spin_lock_irq+0x6f/0x80 kernel/locking/spinlock.c:167 [< inline >] spin_lock_irq include/linux/spinlock.h:332 [] kvm_irqfd_release+0x2f/0x120 arch/x86/kvm/../../../virt/kvm/eventfd.c:584 [] kvm_vm_release+0x3a/0x50 arch/x86/kvm/../../../virt/kvm/kvm_main.c:752 [] __fput+0x236/0x780 fs/file_table.c:208 [] ____fput+0x15/0x20 fs/file_table.c:244 [] task_work_run+0xf6/0x170 kernel/task_work.c:115 [< inline >] exit_task_work include/linux/task_work.h:21 [] do_exit+0xa62/0x2c80 kernel/exit.c:748 [< inline >] SYSC_exit kernel/exit.c:847 [] SyS_exit+0x22/0x30 kernel/exit.c:845 [] entry_SYSCALL_64_fastpath+0x23/0xc1 arch/x86/entry/entry_64.S:207 Memory state around the buggy address: ffff880060888b00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ffff880060888b80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff >ffff880060888c00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ^ ffff880060888c80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ffff880060888d00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ================================================================== BUG: unable to handle kernel paging request at ffff880060888c64 IP: [< inline >] debug_spin_lock_before kernel/locking/spinlock_debug.c:83 IP: [] do_raw_spin_lock+0x3e/0x2b0 kernel/locking/spinlock_debug.c:135 PGD a3bc067 PUD a3bf067 PMD 7fdfc067 PTE 8000000060888060 Oops: 0000 [#2] SMP DEBUG_PAGEALLOC KASAN Modules linked in: CPU: 2 PID: 7084 Comm: a.out Tainted: G B D 4.7.0-rc4+ #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 task: ffff880060a517c0 ti: ffff880060b70000 task.ti: ffff880060b70000 RIP: 0010:[] [] do_raw_spin_lock+0x3e/0x2b0 RSP: 0018:ffff880060b77c40 EFLAGS: 00010092 RAX: ffff880060a517c0 RBX: ffff880060888c60 RCX: 0000000000000000 RDX: 0000000000000004 RSI: 0000000000000001 RDI: 0000000000000000 RBP: ffff880060b77c68 R08: 0000000000000001 R09: 0000000000000000 R10: ffff880060b77bce R11: 0000000000000000 R12: ffff880063813174 R13: ffff880060888c98 R14: ffff88003ad2d6a8 R15: ffff880060888c60 FS: 00007f34165a4700(0000) GS:ffff88006d400000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffff880060888c64 CR3: 0000000060013000 CR4: 00000000000026e0 Stack: ffff880060888c60 ffff880063813174 ffff880060888c98 ffff88003ad2d6a8 ffff880060888c60 ffff880060b77c88 ffffffff86a969df ffffffff81073eff ffff880060888000 ffff880060b77cc8 ffffffff81073eff 00000000000000c0 Call Trace: [< inline >] __raw_spin_lock_irq include/linux/spinlock_api_smp.h:131 [] _raw_spin_lock_irq+0x6f/0x80 kernel/locking/spinlock.c:167 [< inline >] spin_lock_irq include/linux/spinlock.h:332 [] kvm_irqfd_release+0x2f/0x120 arch/x86/kvm/../../../virt/kvm/eventfd.c:584 [] kvm_vm_release+0x3a/0x50 arch/x86/kvm/../../../virt/kvm/kvm_main.c:752 [] __fput+0x236/0x780 fs/file_table.c:208 [] ____fput+0x15/0x20 fs/file_table.c:244 [] task_work_run+0xf6/0x170 kernel/task_work.c:115 [< inline >] exit_task_work include/linux/task_work.h:21 [] do_exit+0xa62/0x2c80 kernel/exit.c:748 [< inline >] SYSC_exit kernel/exit.c:847 [] SyS_exit+0x22/0x30 kernel/exit.c:845 [] entry_SYSCALL_64_fastpath+0x23/0xc1 arch/x86/entry/entry_64.S:207 Code: 55 41 54 53 48 89 fb 48 83 c7 04 48 89 fa 48 c1 ea 03 0f b6 14 02 48 89 f8 83 e0 07 83 c0 03 38 d0 7c 08 84 d2 0f 85 3e 02 00 00 <81> 7b 04 ad 4e ad de 0f 85 b9 01 00 00 4c 8d 63 10 48 b8 00 00 RIP [< inline >] debug_spin_lock_before kernel/locking/spinlock_debug.c:83 RIP [] do_raw_spin_lock+0x3e/0x2b0 kernel/locking/spinlock_debug.c:135 RSP CR2: ffff880060888c64 ---[ end trace 423f749510e6178a ]--- Fixing recursive fault but reboot is needed! BUG: scheduling while atomic: a.out/7084/0x00000002 lockdep is turned off. Modules linked in: irq event stamp: 0 hardirqs last enabled at (0): [< (null)>] (null) hardirqs last disabled at (0): [] copy_process.part.38+0x11dd/0x5b20 kernel/fork.c:1428 softirqs last enabled at (0): [] copy_process.part.38+0x127e/0x5b20 kernel/fork.c:1431 softirqs last disabled at (0): [< (null)>] (null) CPU: 2 PID: 7084 Comm: a.out Tainted: G B D 4.7.0-rc4+ #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 ffffffff880b58e0 ffff880060b776d8 ffffffff82cc62cf ffffffff60a517c0 fffffbfff1016b1c ffff880060a517c0 0000000000000002 ffff880060b70000 0000000000000009 ffff88006d421580 ffff880060b776f8 ffffffff813ee349 Call Trace: [< inline >] __dump_stack lib/dump_stack.c:15 [] dump_stack+0x12e/0x18f lib/dump_stack.c:51 [] __schedule_bug+0xb9/0xe0 kernel/sched/core.c:3163 [< inline >] schedule_debug kernel/sched/core.c:3178 [] __schedule+0x128a/0x1ca0 kernel/sched/core.c:3289 [] schedule+0x97/0x1c0 kernel/sched/core.c:3375 [] do_exit+0x1dc0/0x2c80 kernel/exit.c:698 [] oops_end+0xa1/0xd0 arch/x86/kernel/dumpstack.c:252 [] no_context+0x2d1/0x8f0 arch/x86/mm/fault.c:795 [] __bad_area_nosemaphore+0x1fc/0x3e0 arch/x86/mm/fault.c:881 [] bad_area_nosemaphore+0x33/0x40 arch/x86/mm/fault.c:888 [] __do_page_fault+0x193/0xbb0 arch/x86/mm/fault.c:1298 [] trace_do_page_fault+0xdf/0x5b0 arch/x86/mm/fault.c:1449 [] do_async_page_fault+0x14/0xd0 arch/x86/kernel/kvm.c:265 [] async_page_fault+0x28/0x30 arch/x86/entry/entry_64.S:923 [< inline >] __raw_spin_lock_irq include/linux/spinlock_api_smp.h:131 [] _raw_spin_lock_irq+0x6f/0x80 kernel/locking/spinlock.c:167 [< inline >] spin_lock_irq include/linux/spinlock.h:332 [] kvm_irqfd_release+0x2f/0x120 arch/x86/kvm/../../../virt/kvm/eventfd.c:584 [] kvm_vm_release+0x3a/0x50 arch/x86/kvm/../../../virt/kvm/kvm_main.c:752 [] __fput+0x236/0x780 fs/file_table.c:208 [] ____fput+0x15/0x20 fs/file_table.c:244 [] task_work_run+0xf6/0x170 kernel/task_work.c:115 [< inline >] exit_task_work include/linux/task_work.h:21 [] do_exit+0xa62/0x2c80 kernel/exit.c:748 [< inline >] SYSC_exit kernel/exit.c:847 [] SyS_exit+0x22/0x30 kernel/exit.c:845 [] entry_SYSCALL_64_fastpath+0x23/0xc1 arch/x86/entry/entry_64.S:207 Run in a parallel loop: // autogenerated by syzkaller (http://github.com/google/syzkaller) #include #include #include #include #include long r[9]; void* thr(void* arg) { switch ((long)arg) { case 0: r[0] = syscall(SYS_mmap, 0x20000000ul, 0x16000ul, 0x3ul, 0x32ul, 0xfffffffffffffffful, 0x0ul); break; case 1: r[2] = syscall(SYS_open, "/dev/kvm", 0x540ul, 0, 0, 0); break; case 2: r[3] = syscall(SYS_ioctl, r[2], 0xae01ul, 0x0ul, 0, 0, 0); break; case 3: r[4] = syscall(SYS_ioctl, r[3], 0xae41ul, 0x1ul, 0, 0, 0); break; case 4: r[5] = syscall(SYS_ioctl, r[4], 0xae80ul, 0, 0, 0, 0); break; case 5: r[6] = syscall(SYS_ioctl, r[4], 0xae80ul, 0, 0, 0, 0); break; case 6: r[7] = syscall(SYS_ioctl, r[4], 0xae80ul, 0, 0, 0, 0); break; case 7: r[8] = syscall(SYS_ioctl, r[4], 0x8040ae9ful, 0x20014fe4ul, 0, 0, 0); break; } return 0; } int main() { long i; pthread_t th[8]; syscall(SYS_mmap, 0x20000000ul, 0x16000ul, 0x3ul, 0x32ul, 0xfffffffffffffffful, 0x0ul); srand(getpid()); memset(r, -1, sizeof(r)); for (i = 0; i < 8; i++) { pthread_create(&th[i], 0, thr, (void*)i); } for (i = 0; i < 8; i++) { pthread_join(th[i], 0); } for (i = 0; i < 8; i++) { pthread_create(&th[i], 0, thr, (void*)i); if ((rand() % 2) == 0) usleep(rand() % 10000); } for (i = 0; i < 8; i++) { pthread_join(th[i], 0); } return 0; } On commit 67016f6cdfd079e632bbc49e33178b2d558c120a (Jun 20).