lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Sun, 22 Sep 2013 12:33:53 +0300
From:	Gleb Natapov <gleb@...hat.com>
To:	Paolo Bonzini <pbonzini@...hat.com>
Cc:	linux-kernel@...r.kernel.org
Subject: Re: [PATCH v2 2/3] KVM: x86: prevent setting unsupported XSAVE states

On Mon, Sep 16, 2013 at 04:26:30PM +0200, Paolo Bonzini wrote:
> A guest can still attempt to save and restore XSAVE states even if they
> have been masked in CPUID leaf 0Dh.  This usually is not visible to
> the guest, but is still wrong: "Any attempt to set a reserved bit (as
> determined by the contents of EAX and EDX after executing CPUID with
> EAX=0DH, ECX= 0H) in XCR0 for a given processor will result in a #GP
> exception".
> 
> The patch also performs the same checks as __kvm_set_xcr in KVM_SET_XSAVE.
> This catches migration from newer to older kernel/processor before the
> guest starts running.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@...hat.com>
> ---
>  arch/x86/include/asm/kvm_host.h |  1 +
>  arch/x86/kvm/cpuid.c            |  7 +++++++
>  arch/x86/kvm/x86.c              | 17 ++++++++++++++---
>  3 files changed, 22 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> index c76ff74..1553542 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -389,6 +389,7 @@ struct kvm_vcpu_arch {
>  
>  	struct fpu guest_fpu;
>  	u64 xcr0;
> +	u64 supported_xcr0;
>  
Lets prefix it with guest_.

>  	struct kvm_pio_request pio;
>  	void *pio_data;
> diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
> index a03a9fa..fa754a8 100644
> --- a/arch/x86/kvm/cpuid.c
> +++ b/arch/x86/kvm/cpuid.c
> @@ -46,6 +46,13 @@ void kvm_update_cpuid(struct kvm_vcpu *vcpu)
>  			apic->lapic_timer.timer_mode_mask = 1 << 17;
>  	}
>  
> +	best = kvm_find_cpuid_entry(vcpu, 0xD, 0);
> +	if (!best)
> +		return;
If QMEU will set AVX in 0xD and then remove cpuid leaf at all
supported_xcr0  will still have it.

> +	vcpu->arch.supported_xcr0 =
> +		(best->eax | ((u64)best->edx << 32)) &
> +		host_xcr0 & KVM_SUPPORTED_XCR0;
> +
>  	kvm_pmu_cpuid_update(vcpu);
>  }
>  
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index e5ca72a..cc8c403 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -586,7 +586,7 @@ int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
>  		return 1;
>  	if ((xcr0 & XSTATE_YMM) && !(xcr0 & XSTATE_SSE))
>  		return 1;
> -	if (xcr0 & ~host_xcr0)
> +	if (xcr0 & ~vcpu->arch.supported_xcr0)
>  		return 1;
>  	kvm_put_guest_xcr0(vcpu);
>  	vcpu->arch.xcr0 = xcr0;
> @@ -3003,10 +3003,19 @@ static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu,
>  	u64 xstate_bv =
>  		*(u64 *)&guest_xsave->region[XSAVE_HDR_OFFSET / sizeof(u32)];
>  
> -	if (cpu_has_xsave)
> +	if (cpu_has_xsave) {
> +		/*
> +		 * Here we allow setting states that are not present in
> +		 * CPUID leaf 0xD, index 0, EDX:EAX.  This is for compatibility
> +		 * with old userspace.
> +		 */
> +		if (xstate_bv & ~KVM_SUPPORTED_XCR0)
> +			return -EINVAL;
> +		if (xstate_bv & ~host_xcr0)
> +			return -EINVAL;
>  		memcpy(&vcpu->arch.guest_fpu.state->xsave,
>  			guest_xsave->region, xstate_size);
> -	else {
> +	} else {
>  		if (xstate_bv & ~XSTATE_FPSSE)
>  			return -EINVAL;
>  		memcpy(&vcpu->arch.guest_fpu.state->fxsave,
> @@ -6940,6 +6948,9 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
>  
>  	vcpu->arch.ia32_tsc_adjust_msr = 0x0;
>  	vcpu->arch.pv_time_enabled = false;
> +
> +	vcpu->arch.supported_xcr0 = XSTATE_FPSSE;
> +
Why is this needed? It will make make __kvm_set_xcr() succeed if attempt
is made to set SSE bit when it is not supported in cpuid. This may not
be an issue in practice, but for clarity it is better for supported_xcr0
to contain only what is supported in guest's cpuid bits and handle the
fact that FP/SSE state should always be copied to/from userspace in
kvm_vcpu_ioctl_x86_(set|get)_xsave functions.

>  	kvm_async_pf_hash_reset(vcpu);
>  	kvm_pmu_init(vcpu);
>  
> -- 
> 1.8.3.1
> 

--
			Gleb.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ