From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753010AbbCKNEC (ORCPT ); Wed, 11 Mar 2015 09:04:02 -0400 Received: from mail-wi0-f170.google.com ([209.85.212.170]:33176 "EHLO mail-wi0-f170.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751693AbbCKNEA convert rfc822-to-8bit (ORCPT ); Wed, 11 Mar 2015 09:04:00 -0400 Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2070.6\)) Subject: Re: Testcases for "eip canonical" kvm fixes? From: Nadav Amit In-Reply-To: Date: Wed, 11 Mar 2015 15:03:59 +0200 Cc: Nadav Amit , Paolo Bonzini , X86 ML , Linux Kernel Mailing List Content-Transfer-Encoding: 8BIT Message-Id: References: To: Denys Vlasenko X-Mailer: Apple Mail (2.2070.6) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Automatic testings. I am working on a research paper regarding it, so I’ll publish the details (hopefully) in the near future. Nadav Denys Vlasenko wrote: > Hi, > > I wonder how did you trigger the bug for your following fix? > > > commit 234f3ce485d54017f15cf5e0699cff4100121601 > Author: Nadav Amit > Date: Thu Sep 18 22:39:38 2014 +0300 > > KVM: x86: Emulator fixes for eip canonical checks on near branches > > Before changing rip (during jmp, call, ret, etc.) the target > should be asserted > to be canonical one, as real CPUs do. During sysret, both target > rsp and rip > should be canonical. If any of these values is noncanonical, a #GP exception > should occur. The exception to this rule are syscall and sysenter > instructions > in which the assigned rip is checked during the assignment to the relevant > MSRs. > > This patch fixes the emulator to behave as real CPUs do for near branches. > Far branches are handled by the next patch. > > > Non-canonical addresses result in #GP, but KVM doesn't > intercept guest #GP, according to code below: > > static void update_exception_bitmap(struct kvm_vcpu *vcpu) > { > u32 eb; > > eb = (1u << PF_VECTOR) | (1u << UD_VECTOR) | (1u << MC_VECTOR) | > (1u << NM_VECTOR) | (1u << DB_VECTOR); > if ((vcpu->guest_debug & > (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)) == > (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)) > eb |= 1u << BP_VECTOR; > if (to_vmx(vcpu)->rmode.vm86_active) > eb = ~0; > if (enable_ept) > eb &= ~(1u << PF_VECTOR); /* bypass_guest_pf = 0 */ > if (vcpu->fpu_active) > eb &= ~(1u << NM_VECTOR); > > /* When we are running a nested L2 guest and L1 specified for it a > * certain exception bitmap, we must trap the same exceptions and pass > * them to L1. When running L2, we will only handle the exceptions > * specified above if L1 did not want them. > */ > if (is_guest_mode(vcpu)) > eb |= get_vmcs12(vcpu)->exception_bitmap; > > vmcs_write32(EXCEPTION_BITMAP, eb); > } > > > That what seems to be happening to me when I try to reproduce > the bug on unpatched kernel: CPU simply emulates #GP, and > everything works as it should. > > In particular: > I'm trying "RET far" with noncanonical address on stack (and valid CS). > I expect that buggy behavior would be that #GP happens > after "RET far". Instead, #GP happens _on_ "RET far" insn. > > -- > vda