diff mbox

KVM: VMX: mark unusable segment as nonpresent

Message ID 20130628101718.GC25199@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Gleb Natapov June 28, 2013, 10:17 a.m. UTC
Some userspaces do not preserve unusable property. Since usable
segment has to be present according to VMX spec we can use present
property to amend userspace bug by making unusable segment always
nonpresent. vmx_segment_access_rights() already marks nonpresent segment
as unusable.

Cc: stable@vger.kernel.org # 3.9+
Reported-by: Stefan Pietsch <stefan.pietsch@lsexperts.de>
Tested-by: Stefan Pietsch <stefan.pietsch@lsexperts.de>
Signed-off-by: Gleb Natapov <gleb@redhat.com>

--
			Gleb.
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Paolo Bonzini July 2, 2013, 8:15 a.m. UTC | #1
Il 28/06/2013 12:17, Gleb Natapov ha scritto:
> Some userspaces do not preserve unusable property. Since usable
> segment has to be present according to VMX spec we can use present
> property to amend userspace bug by making unusable segment always
> nonpresent. vmx_segment_access_rights() already marks nonpresent segment
> as unusable.
> 
> Cc: stable@vger.kernel.org # 3.9+
> Reported-by: Stefan Pietsch <stefan.pietsch@lsexperts.de>
> Tested-by: Stefan Pietsch <stefan.pietsch@lsexperts.de>
> Signed-off-by: Gleb Natapov <gleb@redhat.com>
> 
> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index 260a919..5402c94 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -3399,15 +3399,22 @@ static void vmx_get_segment(struct kvm_vcpu *vcpu,
>  	var->limit = vmx_read_guest_seg_limit(vmx, seg);
>  	var->selector = vmx_read_guest_seg_selector(vmx, seg);
>  	ar = vmx_read_guest_seg_ar(vmx, seg);
> +	var->unusable = (ar >> 16) & 1;
>  	var->type = ar & 15;
>  	var->s = (ar >> 4) & 1;
>  	var->dpl = (ar >> 5) & 3;
> -	var->present = (ar >> 7) & 1;
> +	/*
> +	 * Some userspaces do not preserve unusable property. Since usable
> +	 * segment has to be present according to VMX spec we can use present
> +	 * property to amend userspace bug by making unusable segment always
> +	 * nonpresent. vmx_segment_access_rights() already marks nonpresent
> +	 * segment as unusable.
> +	 */
> +	var->present = !var->unusable;
>  	var->avl = (ar >> 12) & 1;
>  	var->l = (ar >> 13) & 1;
>  	var->db = (ar >> 14) & 1;
>  	var->g = (ar >> 15) & 1;
> -	var->unusable = (ar >> 16) & 1;
>  }
>  
>  static u64 vmx_get_segment_base(struct kvm_vcpu *vcpu, int seg)
> --
> 			Gleb.
> 

Looks good, but for now I'm leaving it out of the 3.11 pull request.
Applied to queue.

Paolo
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Gleb Natapov July 2, 2013, 8:18 a.m. UTC | #2
On Tue, Jul 02, 2013 at 10:15:54AM +0200, Paolo Bonzini wrote:
> Il 28/06/2013 12:17, Gleb Natapov ha scritto:
> > Some userspaces do not preserve unusable property. Since usable
> > segment has to be present according to VMX spec we can use present
> > property to amend userspace bug by making unusable segment always
> > nonpresent. vmx_segment_access_rights() already marks nonpresent segment
> > as unusable.
> > 
> > Cc: stable@vger.kernel.org # 3.9+
> > Reported-by: Stefan Pietsch <stefan.pietsch@lsexperts.de>
> > Tested-by: Stefan Pietsch <stefan.pietsch@lsexperts.de>
> > Signed-off-by: Gleb Natapov <gleb@redhat.com>
> > 
> > diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> > index 260a919..5402c94 100644
> > --- a/arch/x86/kvm/vmx.c
> > +++ b/arch/x86/kvm/vmx.c
> > @@ -3399,15 +3399,22 @@ static void vmx_get_segment(struct kvm_vcpu *vcpu,
> >  	var->limit = vmx_read_guest_seg_limit(vmx, seg);
> >  	var->selector = vmx_read_guest_seg_selector(vmx, seg);
> >  	ar = vmx_read_guest_seg_ar(vmx, seg);
> > +	var->unusable = (ar >> 16) & 1;
> >  	var->type = ar & 15;
> >  	var->s = (ar >> 4) & 1;
> >  	var->dpl = (ar >> 5) & 3;
> > -	var->present = (ar >> 7) & 1;
> > +	/*
> > +	 * Some userspaces do not preserve unusable property. Since usable
> > +	 * segment has to be present according to VMX spec we can use present
> > +	 * property to amend userspace bug by making unusable segment always
> > +	 * nonpresent. vmx_segment_access_rights() already marks nonpresent
> > +	 * segment as unusable.
> > +	 */
> > +	var->present = !var->unusable;
> >  	var->avl = (ar >> 12) & 1;
> >  	var->l = (ar >> 13) & 1;
> >  	var->db = (ar >> 14) & 1;
> >  	var->g = (ar >> 15) & 1;
> > -	var->unusable = (ar >> 16) & 1;
> >  }
> >  
> >  static u64 vmx_get_segment_base(struct kvm_vcpu *vcpu, int seg)
> > --
> > 			Gleb.
> > 
> 
> Looks good, but for now I'm leaving it out of the 3.11 pull request.
> Applied to queue.
> 
It affects people so lets target it to 3.10/3.9-stable.

--
			Gleb.
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 260a919..5402c94 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -3399,15 +3399,22 @@  static void vmx_get_segment(struct kvm_vcpu *vcpu,
 	var->limit = vmx_read_guest_seg_limit(vmx, seg);
 	var->selector = vmx_read_guest_seg_selector(vmx, seg);
 	ar = vmx_read_guest_seg_ar(vmx, seg);
+	var->unusable = (ar >> 16) & 1;
 	var->type = ar & 15;
 	var->s = (ar >> 4) & 1;
 	var->dpl = (ar >> 5) & 3;
-	var->present = (ar >> 7) & 1;
+	/*
+	 * Some userspaces do not preserve unusable property. Since usable
+	 * segment has to be present according to VMX spec we can use present
+	 * property to amend userspace bug by making unusable segment always
+	 * nonpresent. vmx_segment_access_rights() already marks nonpresent
+	 * segment as unusable.
+	 */
+	var->present = !var->unusable;
 	var->avl = (ar >> 12) & 1;
 	var->l = (ar >> 13) & 1;
 	var->db = (ar >> 14) & 1;
 	var->g = (ar >> 15) & 1;
-	var->unusable = (ar >> 16) & 1;
 }
 
 static u64 vmx_get_segment_base(struct kvm_vcpu *vcpu, int seg)