Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752543AbdLMJ6d (ORCPT ); Wed, 13 Dec 2017 04:58:33 -0500 Received: from mail-ot0-f194.google.com ([74.125.82.194]:35615 "EHLO mail-ot0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751129AbdLMJ6b (ORCPT ); Wed, 13 Dec 2017 04:58:31 -0500 X-Google-Smtp-Source: ACJfBov+K8DssfbC5d+TaUmqWfO0aouGHkSdIgfAjGnpa/EH3IkXV5ItDh4eti82nUp7VFD+PFPiwF3y9822UZI5fqQ= MIME-Version: 1.0 In-Reply-To: <1513158796-6129-1-git-send-email-pbonzini@redhat.com> References: <1513158796-6129-1-git-send-email-pbonzini@redhat.com> From: Wanpeng Li Date: Wed, 13 Dec 2017 17:58:28 +0800 Message-ID: Subject: Re: [PATCH] KVM: x86: fix escape of guest dr6 to the host To: Paolo Bonzini Cc: "linux-kernel@vger.kernel.org" , kvm , =?UTF-8?B?UmFkaW0gS3LEjW3DocWZ?= , David Hildenbrand , Dmitry Vyukov , Wanpeng Li Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from quoted-printable to 8bit by nfs id vBD9wd0B024525 Content-Length: 2325 Lines: 64 2017-12-13 17:53 GMT+08:00 Paolo Bonzini : > 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 > > _copy_from_user+0x5b/0x90 > SyS_timer_create+0x33/0x80 > entry_SYSCALL_64_fastpath+0x23/0x9a > > The 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. > > Reported-by: Dmitry Vyukov > Cc: Paolo Bonzini > Cc: Radim Krčmář > Cc: David Hildenbrand > Cc: Dmitry Vyukov > Reviewed-by: David Hildenbrand > Signed-off-by: Wanpeng Li Thanks for the help! :) Regards, Wanpeng Li > --- > arch/x86/kvm/x86.c | 6 ++++++ > 1 file changed, 6 insertions(+) > > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c > index 9212dad176a7..eed73217e96f 100644 > --- a/arch/x86/kvm/x86.c > +++ b/arch/x86/kvm/x86.c > @@ -2951,6 +2951,12 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) > pagefault_enable(); > kvm_x86_ops->vcpu_put(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, > -- > 1.8.3.1 >