kernel BUG at arch/x86/kvm/mmu.c:LINE!

124 views
Skip to first unread message

syzbot

unread,
Nov 1, 2017, 4:25:02 PM11/1/17
to h...@zytor.com, k...@vger.kernel.org, linux-...@vger.kernel.org, mi...@redhat.com, pbon...@redhat.com, rkr...@redhat.com, syzkall...@googlegroups.com, tg...@linutronix.de, x...@kernel.org
Hello,

syzkaller hit the following crash on
bb70832dd42b298d4303fd054bf18a78650ff04a
git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/master
compiler: gcc (GCC) 7.1.1 20170620
.config is attached
Raw console output is attached.
C reproducer is attached
syzkaller reproducer is attached. See https://goo.gl/kgGztJ
for information about syzkaller reproducers


------------[ cut here ]------------
kernel BUG at arch/x86/kvm/mmu.c:1194!
invalid opcode: 0000 [#1] SMP KASAN
Dumping ftrace buffer:
(ftrace buffer empty)
Modules linked in:
CPU: 0 PID: 2997 Comm: syzkaller760858 Not tainted
4.13.0-rc5-next-20170817+ #5
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
task: ffff88006ce641c0 task.stack: ffff880069448000
RIP: 0010:pte_list_remove+0x3ae/0x3c0 arch/x86/kvm/mmu.c:1193
RSP: 0018:ffff88006944eee8 EFLAGS: 00010286
RAX: 0000000000000028 RBX: ffff88003debd700 RCX: 0000000000000000
RDX: 0000000000000028 RSI: 1ffff1000d289d9d RDI: ffffed000d289dd1
RBP: ffff88006944ef28 R08: 0000000000000000 R09: 1ffff1000d289d6f
R10: ffff88006944f2d0 R11: ffffffff85b2cbf8 R12: ffff88003cab9000
R13: 0000000000000000 R14: ffff88003d4d5cf0 R15: ffff88003d4d5d18
FS: 0000000000000000(0000) GS:ffff88003ec00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000202ecfa3 CR3: 000000003976d000 CR4: 00000000000026f0
Call Trace:
rmap_remove arch/x86/kvm/mmu.c:1270 [inline]
drop_spte+0x15a/0x250 arch/x86/kvm/mmu.c:1352
mmu_page_zap_pte+0x224/0x340 arch/x86/kvm/mmu.c:2484
kvm_mmu_page_unlink_children arch/x86/kvm/mmu.c:2506 [inline]
kvm_mmu_prepare_zap_page+0x1c5/0x1310 arch/x86/kvm/mmu.c:2550
kvm_zap_obsolete_pages arch/x86/kvm/mmu.c:5225 [inline]
kvm_mmu_invalidate_zap_all_pages+0x4a0/0x680 arch/x86/kvm/mmu.c:5266
kvm_arch_flush_shadow_all+0x15/0x20 arch/x86/kvm/x86.c:8398
kvm_mmu_notifier_release+0x59/0x90
arch/x86/kvm/../../../virt/kvm/kvm_main.c:508
__mmu_notifier_release+0x1d5/0x690 mm/mmu_notifier.c:75
mmu_notifier_release include/linux/mmu_notifier.h:235 [inline]
exit_mmap+0x479/0x560 mm/mmap.c:2982
__mmput kernel/fork.c:906 [inline]
mmput+0x223/0x6e0 kernel/fork.c:928
exit_mm kernel/exit.c:544 [inline]
do_exit+0x9a1/0x1b30 kernel/exit.c:852
do_group_exit+0x149/0x400 kernel/exit.c:968
SYSC_exit_group kernel/exit.c:979 [inline]
SyS_exit_group+0x1d/0x20 kernel/exit.c:977
entry_SYSCALL_64_fastpath+0x1f/0xbe
RIP: 0033:0x436c49
RSP: 002b:00007ffdd78a9b88 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7
RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 0000000000436c49
RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
RBP: 0000000000000006 R08: 000000000000003c R09: 00000000000000e7
R10: ffffffffffffffc0 R11: 0000000000000246 R12: 0000000000000000
R13: 0000000000000004 R14: 0000000000000004 R15: 0000000020cde000
Code: f9 59 5e 00 48 8b 75 d0 48 c7 c7 40 4d e2 84 e8 7e 3a 49 00 0f 0b e8
e2 59 5e 00 48 8b 75 d0 48 c7 c7 00 4d e2 84 e8 67 3a 49 00 <0f> 0b 4c 89
ef e8 18 c4 92 00 e9 01 fe ff ff 0f 1f 00 55 48 89
RIP: pte_list_remove+0x3ae/0x3c0 arch/x86/kvm/mmu.c:1193 RSP:
ffff88006944eee8
---[ end trace 0ef225aa830b2789 ]---


---
This bug is generated by a dumb bot. It may contain errors.
See https://goo.gl/tpsmEJ for details.
Direct all questions to syzk...@googlegroups.com.
Please credit me with: Reported-by: syzbot <syzk...@googlegroups.com>

syzbot will keep track of this bug report.
Once a fix for this bug is committed, please reply to this email with:
#syz fix: exact-commit-title
To mark this as a duplicate of another syzbot report, please reply with:
#syz dup: exact-subject-of-another-report
If it's a one-off invalid bug report, please reply with:
#syz invalid
Note: if the crash happens again, it will cause creation of a new bug
report.
Note: all commands must start from beginning of the line.
config.txt
raw.log
repro.txt
repro.c

Eric Biggers

unread,
Jan 19, 2018, 3:22:46 AM1/19/18
to k...@vger.kernel.org, Paolo Bonzini, Radim Krčmář, linux-...@vger.kernel.org, syzkall...@googlegroups.com, Eric Biggers, sta...@vger.kernel.org
From: Eric Biggers <ebig...@google.com>

Memslots must not overlap in guest physical memory, since otherwise some
guest physical addresses will not uniquely map to a memslot. Yet, the
overlap check in __kvm_set_memory_region() allows a memslot that
overlaps one of the "private" memslots, e.g. the memslot reserved for
the TSS on x86.

This seems to be a very old bug that was introduced years ago when
private memory slots were first added. It seems that later refactoring
incorrectly assumed this bug was intentional and preserved it.

Fix it by removing the loophole for private memslots, so we just check
for overlap against all memslots.

This bug was found by syzkaller, which used a memslot overlap to make
pte_list_remove() be called for the wrong memslot, hitting a BUG():

pte_list_remove: 000000007185ed42 0->BUG
kernel BUG at arch/x86/kvm/mmu.c:1209!
[...]
RIP: 0010:pte_list_remove+0x107/0x110 arch/x86/kvm/mmu.c:1208
[...]
Call Trace:
mmu_page_zap_pte+0x7e/0xd0 arch/x86/kvm/mmu.c:2499
kvm_mmu_page_unlink_children arch/x86/kvm/mmu.c:2521 [inline]
kvm_mmu_prepare_zap_page+0x4f/0x340 arch/x86/kvm/mmu.c:2565
kvm_zap_obsolete_pages arch/x86/kvm/mmu.c:5348 [inline]
kvm_mmu_invalidate_zap_all_pages+0xa6/0x100 arch/x86/kvm/mmu.c:5389
kvm_mmu_notifier_release+0x4f/0x80 arch/x86/kvm/../../../virt/kvm/kvm_main.c:468
__mmu_notifier_release+0x63/0x100 mm/mmu_notifier.c:75
mmu_notifier_release include/linux/mmu_notifier.h:244 [inline]
exit_mmap+0x160/0x170 mm/mmap.c:3009
__mmput kernel/fork.c:966 [inline]
mmput+0x44/0xd0 kernel/fork.c:987
exit_mm kernel/exit.c:544 [inline]
do_exit+0x24a/0xb50 kernel/exit.c:856
do_group_exit+0x34/0xb0 kernel/exit.c:972
SYSC_exit_group kernel/exit.c:983 [inline]
SyS_exit_group+0xb/0x10 kernel/exit.c:981
entry_SYSCALL_64_fastpath+0x1e/0x8b

Reproducer:

#include <fcntl.h>
#include <linux/kvm.h>
#include <sys/ioctl.h>

int main()
{
static char buf[4096*3] __attribute__((aligned(4096)));
int kvm, vm, cpu;
struct kvm_mp_state mp_state = { KVM_MP_STATE_SIPI_RECEIVED };
struct kvm_userspace_memory_region memreg = {
.memory_size = sizeof(buf),
.userspace_addr = (__u64)buf,
};

kvm = open("/dev/kvm", O_RDWR);
vm = ioctl(kvm, KVM_CREATE_VM, 0);
ioctl(vm, KVM_CREATE_IRQCHIP);
cpu = ioctl(vm, KVM_CREATE_VCPU, 0);
ioctl(cpu, KVM_SET_MP_STATE, &mp_state);
ioctl(vm, KVM_SET_TSS_ADDR, 0);
ioctl(cpu, KVM_RUN, 0);
ioctl(vm, KVM_SET_USER_MEMORY_REGION, &memreg);
}

Reported-by: syzbot <syzk...@googlegroups.com>
Fixes: e0d62c7f4860 ("KVM: Add kernel-internal memory slots")
Cc: <sta...@vger.kernel.org> # v2.6.25+
Signed-off-by: Eric Biggers <ebig...@google.com>
---
virt/kvm/kvm_main.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 210bf820385a..e536977e7b6d 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -974,8 +974,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
/* Check for overlaps */
r = -EEXIST;
kvm_for_each_memslot(slot, __kvm_memslots(kvm, as_id)) {
- if ((slot->id >= KVM_USER_MEM_SLOTS) ||
- (slot->id == id))
+ if (slot->id == id)
continue;
if (!((base_gfn + npages <= slot->base_gfn) ||
(base_gfn >= slot->base_gfn + slot->npages)))
--
2.16.0

Wanpeng Li

unread,
Jan 19, 2018, 4:01:59 AM1/19/18
to Eric Biggers, kvm, Paolo Bonzini, Radim Krčmář, linux-...@vger.kernel.org, syzkall...@googlegroups.com, Eric Biggers, # v3 . 10+
Please refer to this one. https://patchwork.kernel.org/patch/9645377/

Regards,
Wanpeng Li

Wanpeng Li

unread,
Jan 19, 2018, 4:03:48 AM1/19/18
to Eric Biggers, kvm, Paolo Bonzini, Radim Krčmář, linux-...@vger.kernel.org, syzkall...@googlegroups.com, Eric Biggers, # v3 . 10+

Eric Biggers

unread,
Jan 19, 2018, 1:57:20 PM1/19/18
to Wanpeng Li, kvm, Paolo Bonzini, Radim Krčmář, linux-...@vger.kernel.org, syzkall...@googlegroups.com, Eric Biggers, # v3 . 10+, Alex Williamson
+Cc alex.wi...@redhat.com
Ah, so this was reported before, and you sent the same fix. Well, it was never
applied, so the bug is still there, and anyone who can use /dev/kvm can trigger
it. So one of these patches needs to be applied, unless there is a better fix.

I don't agree with the "Fixes:" line in your version of the patch. The bug was
actually there prior to 5419369ed, which might explain why that commit seemed to
preserve the behavior intentionally. (Note that KVM_MEMORY_SLOTS did not
include the private memory slots; it was later renamed to KVM_USER_MEM_SLOTS.)

Eric

Eric Biggers

unread,
Jan 30, 2018, 3:49:25 PM1/30/18
to Wanpeng Li, kvm, Paolo Bonzini, Radim Krčmář, linux-...@vger.kernel.org, syzkall...@googlegroups.com, Eric Biggers, # v3 . 10+, Alex Williamson
Ping. Paolo or Radim, can you please consider applying one of these patches?

Eric

Eric Biggers

unread,
Feb 12, 2018, 10:38:25 PM2/12/18
to Wanpeng Li, kvm, Paolo Bonzini, Radim Krčmář, linux-...@vger.kernel.org, syzkall...@googlegroups.com, Eric Biggers, sta...@vger.kernel.org, Alex Williamson
Ping.

Paolo Bonzini

unread,
Feb 13, 2018, 9:38:06 AM2/13/18
to Eric Biggers, Wanpeng Li, kvm, Radim Krčmář, linux-...@vger.kernel.org, syzkall...@googlegroups.com, Eric Biggers, sta...@vger.kernel.org, Alex Williamson
Applied, thanks.

Paolo

Eric Biggers

unread,
Feb 20, 2018, 1:14:35 PM2/20/18
to syzbot, syzkall...@googlegroups.com
Fix is in kvm/queue now:

#syz fix: KVM: mmu: Fix overlap between public and private memslots

- Eric
Reply all
Reply to author
Forward
0 new messages