Patch "KVM: x86: fix escape of guest dr6 to the host" has been added to the 4.4-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
KVM: x86: fix escape of guest dr6 to the host
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
kvm-x86-fix-escape-of-guest-dr6-to-the-host.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
efdab992813fb2ed825745625b83c05032e9cda2Mon Sep 17 00:00:00 2001
From: Wanpeng Li <[email protected]>
Date: Wed, 13 Dec 2017 10:46:40 +0100
Subject: KVM: x86: fix escape of guest dr6 to the host
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
From: Wanpeng Li <[email protected]>
commit efdab992813fb2ed825745625b83c05032e9cda2 upstream.
syzkaller reported:
WARNING: CPU: 0 PID: 12927 at arch/x86/kernel/traps.c:780 do_debug+0x222/0x250
CPU: 0 PID: 12927 Comm: syz-executor Tainted: G OE 4.15.0-rc2+ #16
RIP: 0010:do_debug+0x222/0x250
Call Trace:
<#DB>
debug+0x3e/0x70
RIP: 0010:copy_user_enhanced_fast_string+0x10/0x20
</#DB>
_copy_from_user+0x5b/0x90
SyS_timer_create+0x33/0x80
entry_SYSCALL_64_fastpath+0x23/0x9aThe testcase sets a watchpoint (with perf_event_open) on a buffer that is passed to timer_create() as the struct sigevent argument. In timer_create(), copy_from_user()'s rep movsb triggers the BP. The testcase also sets the debug registers for the guest.
However, KVM only restores host debug registers when the host has active watchpoints, which triggers a race condition when running the testcase with multiple threads. The guest's DR6.BS bit can escape to the host before another thread invokes timer_create(), and do_debug() complains.
The fix is to respect do_debug()'s dr6 invariant when leaving KVM.
--- arch/x86/kvm/x86.c | 6 ++++++ 1 file changed, 6 insertions(+)
arch/x86/kvm/x86.c +6 -0
@@ -2755,6 +2755,12 @@ void kvm_arch_vcpu_put(struct kvm_vcpu * kvm_x86_ops->vcpu_put (vcpu);kvm_put_guest_fpu (vcpu); vcpu->arch.last_host_tsc =rdtsc (); +/* +* If userspace has set any breakpoints or watchpoints, dr6 is restored +* on every vmexit, but if not, we might have a stale dr6 from the +* guest. do_debug expects dr6 to be cleared after it runs, do the same. +*/ +set_debugreg (0 ,6 ); } static int kvm_vcpu_ioctl_get_lapic(struct kvm_vcpu *vcpu,
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/kvm-x86-fix-escape-of-guest-dr6-to-the-host.patch