xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] x86: correct CPUID output for out of bounds input
@ 2016-08-24 15:31 Jan Beulich
  2016-09-01 11:23 ` Andrew Cooper
  2016-09-01 14:27 ` Andrew Cooper
  0 siblings, 2 replies; 11+ messages in thread
From: Jan Beulich @ 2016-08-24 15:31 UTC (permalink / raw)
  To: xen-devel; +Cc: Andrew Cooper

[-- Attachment #1: Type: text/plain, Size: 2540 bytes --]

Another place where we should try to behave like real hardware; see
the code comments.

Signed-off-by: Jan Beulich <jbeulich@suse.com>

--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -3358,6 +3358,31 @@ void hvm_cpuid(unsigned int input, unsig
     if ( !edx )
         edx = &dummy;
 
+    if ( input & 0xffff )
+    {
+        /*
+         * Requests beyond the highest supported leaf within a group return
+         * zero on AMD and the highest basic leaf output on others.
+         */
+        unsigned int lvl;
+
+        hvm_cpuid(input & 0xffff0000, &lvl, NULL, NULL, NULL);
+        if ( ((lvl ^ input) >> 16) || input > lvl )
+        {
+            if ( d->arch.x86_vendor == X86_VENDOR_AMD )
+            {
+                *eax = 0;
+                *ebx = 0;
+                *ecx = 0;
+                *edx = 0;
+                return;
+            }
+            if ( input >> 16 )
+                hvm_cpuid(0, &lvl, NULL, NULL, NULL);
+            input = lvl;
+        }
+    }
+
     if ( cpuid_viridian_leaves(input, eax, ebx, ecx, edx) )
         return;
 
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -944,7 +944,40 @@ void pv_cpuid(struct cpu_user_regs *regs
     struct vcpu *curr = current;
     struct domain *currd = curr->domain;
 
-    leaf = a = regs->eax;
+    leaf = regs->eax;
+
+    if ( leaf & 0xffff )
+    {
+        /*
+         * Requests beyond the highest supported leaf within a group return
+         * zero on AMD and the highest basic leaf output on others.
+         */
+        if ( !is_control_domain(currd) && !is_hardware_domain(currd) )
+            domain_cpuid(currd, leaf & 0xffff0000, 0, &a, &b, &c, &d);
+        else
+            a = cpuid_eax(leaf & 0xffff0000);
+        if ( ((a ^ leaf) >> 16) || leaf > a )
+        {
+            if ( currd->arch.x86_vendor == X86_VENDOR_AMD )
+            {
+                regs->eax = 0;
+                regs->ebx = 0;
+                regs->ecx = 0;
+                regs->edx = 0;
+                return;
+            }
+            if ( leaf >> 16 )
+            {
+                if ( !is_control_domain(currd) && !is_hardware_domain(currd) )
+                    domain_cpuid(currd, 0, 0, &a, &b, &c, &d);
+                else
+                    a = cpuid_eax(0);
+            }
+            leaf = a;
+        }
+    }
+
+    a = regs->eax;
     b = regs->ebx;
     subleaf = c = regs->ecx;
     d = regs->edx;




[-- Attachment #2: x86-CPUID-level-check.patch --]
[-- Type: text/plain, Size: 2587 bytes --]

x86: correct CPUID output for out of bounds input

Another place where we should try to behave like real hardware; see
the code comments.

Signed-off-by: Jan Beulich <jbeulich@suse.com>

--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -3358,6 +3358,31 @@ void hvm_cpuid(unsigned int input, unsig
     if ( !edx )
         edx = &dummy;
 
+    if ( input & 0xffff )
+    {
+        /*
+         * Requests beyond the highest supported leaf within a group return
+         * zero on AMD and the highest basic leaf output on others.
+         */
+        unsigned int lvl;
+
+        hvm_cpuid(input & 0xffff0000, &lvl, NULL, NULL, NULL);
+        if ( ((lvl ^ input) >> 16) || input > lvl )
+        {
+            if ( d->arch.x86_vendor == X86_VENDOR_AMD )
+            {
+                *eax = 0;
+                *ebx = 0;
+                *ecx = 0;
+                *edx = 0;
+                return;
+            }
+            if ( input >> 16 )
+                hvm_cpuid(0, &lvl, NULL, NULL, NULL);
+            input = lvl;
+        }
+    }
+
     if ( cpuid_viridian_leaves(input, eax, ebx, ecx, edx) )
         return;
 
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -944,7 +944,40 @@ void pv_cpuid(struct cpu_user_regs *regs
     struct vcpu *curr = current;
     struct domain *currd = curr->domain;
 
-    leaf = a = regs->eax;
+    leaf = regs->eax;
+
+    if ( leaf & 0xffff )
+    {
+        /*
+         * Requests beyond the highest supported leaf within a group return
+         * zero on AMD and the highest basic leaf output on others.
+         */
+        if ( !is_control_domain(currd) && !is_hardware_domain(currd) )
+            domain_cpuid(currd, leaf & 0xffff0000, 0, &a, &b, &c, &d);
+        else
+            a = cpuid_eax(leaf & 0xffff0000);
+        if ( ((a ^ leaf) >> 16) || leaf > a )
+        {
+            if ( currd->arch.x86_vendor == X86_VENDOR_AMD )
+            {
+                regs->eax = 0;
+                regs->ebx = 0;
+                regs->ecx = 0;
+                regs->edx = 0;
+                return;
+            }
+            if ( leaf >> 16 )
+            {
+                if ( !is_control_domain(currd) && !is_hardware_domain(currd) )
+                    domain_cpuid(currd, 0, 0, &a, &b, &c, &d);
+                else
+                    a = cpuid_eax(0);
+            }
+            leaf = a;
+        }
+    }
+
+    a = regs->eax;
     b = regs->ebx;
     subleaf = c = regs->ecx;
     d = regs->edx;

[-- Attachment #3: Type: text/plain, Size: 127 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] x86: correct CPUID output for out of bounds input
  2016-08-24 15:31 [PATCH] x86: correct CPUID output for out of bounds input Jan Beulich
@ 2016-09-01 11:23 ` Andrew Cooper
  2016-09-01 12:56   ` Jan Beulich
  2016-09-01 14:27 ` Andrew Cooper
  1 sibling, 1 reply; 11+ messages in thread
From: Andrew Cooper @ 2016-09-01 11:23 UTC (permalink / raw)
  To: Jan Beulich, xen-devel

On 24/08/16 16:31, Jan Beulich wrote:
> Another place where we should try to behave like real hardware; see
> the code comments.
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
>
> --- a/xen/arch/x86/hvm/hvm.c
> +++ b/xen/arch/x86/hvm/hvm.c
> @@ -3358,6 +3358,31 @@ void hvm_cpuid(unsigned int input, unsig
>      if ( !edx )
>          edx = &dummy;
>  
> +    if ( input & 0xffff )
> +    {
> +        /*
> +         * Requests beyond the highest supported leaf within a group return
> +         * zero on AMD and the highest basic leaf output on others.
> +         */
> +        unsigned int lvl;
> +
> +        hvm_cpuid(input & 0xffff0000, &lvl, NULL, NULL, NULL);

I have specifically deferred fixing this issue so far, because I don't
want to increase the quantity of recursion with hvm_cpuid().

Also, because of the poor datastructure for domain cpuid, this adds 1
and possibly 2 extra loops over the unordered list.


On the way back from Toronto, I started experimenting with my
full-policy plans, including a structured information layout so
cpuid.basic.max_leaf can be found directly, and starting a guest_cpuid()
function intending to replace both pv_cpuid() and hvm_cpuid() in due course.

Would you be amenable to leaving this issue as-is for now, until there
is a more efficient way of fixing it?

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] x86: correct CPUID output for out of bounds input
  2016-09-01 11:23 ` Andrew Cooper
@ 2016-09-01 12:56   ` Jan Beulich
  2016-09-01 14:17     ` Andrew Cooper
  0 siblings, 1 reply; 11+ messages in thread
From: Jan Beulich @ 2016-09-01 12:56 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: xen-devel

>>> On 01.09.16 at 13:23, <andrew.cooper3@citrix.com> wrote:
> On 24/08/16 16:31, Jan Beulich wrote:
>> Another place where we should try to behave like real hardware; see
>> the code comments.
>>
>> Signed-off-by: Jan Beulich <jbeulich@suse.com>
>>
>> --- a/xen/arch/x86/hvm/hvm.c
>> +++ b/xen/arch/x86/hvm/hvm.c
>> @@ -3358,6 +3358,31 @@ void hvm_cpuid(unsigned int input, unsig
>>      if ( !edx )
>>          edx = &dummy;
>>  
>> +    if ( input & 0xffff )
>> +    {
>> +        /*
>> +         * Requests beyond the highest supported leaf within a group return
>> +         * zero on AMD and the highest basic leaf output on others.
>> +         */
>> +        unsigned int lvl;
>> +
>> +        hvm_cpuid(input & 0xffff0000, &lvl, NULL, NULL, NULL);
> 
> I have specifically deferred fixing this issue so far, because I don't
> want to increase the quantity of recursion with hvm_cpuid().
> 
> Also, because of the poor datastructure for domain cpuid, this adds 1
> and possibly 2 extra loops over the unordered list.
> 
> 
> On the way back from Toronto, I started experimenting with my
> full-policy plans, including a structured information layout so
> cpuid.basic.max_leaf can be found directly, and starting a guest_cpuid()
> function intending to replace both pv_cpuid() and hvm_cpuid() in due course.
> 
> Would you be amenable to leaving this issue as-is for now, until there
> is a more efficient way of fixing it?

If you get this ready for 4.8, yes. Otherwise I think the variant here
is better than nothing until yours arrives.

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] x86: correct CPUID output for out of bounds input
  2016-09-01 12:56   ` Jan Beulich
@ 2016-09-01 14:17     ` Andrew Cooper
  0 siblings, 0 replies; 11+ messages in thread
From: Andrew Cooper @ 2016-09-01 14:17 UTC (permalink / raw)
  To: Jan Beulich; +Cc: xen-devel

On 01/09/16 13:56, Jan Beulich wrote:
>>>> On 01.09.16 at 13:23, <andrew.cooper3@citrix.com> wrote:
>> On 24/08/16 16:31, Jan Beulich wrote:
>>> Another place where we should try to behave like real hardware; see
>>> the code comments.
>>>
>>> Signed-off-by: Jan Beulich <jbeulich@suse.com>
>>>
>>> --- a/xen/arch/x86/hvm/hvm.c
>>> +++ b/xen/arch/x86/hvm/hvm.c
>>> @@ -3358,6 +3358,31 @@ void hvm_cpuid(unsigned int input, unsig
>>>      if ( !edx )
>>>          edx = &dummy;
>>>  
>>> +    if ( input & 0xffff )
>>> +    {
>>> +        /*
>>> +         * Requests beyond the highest supported leaf within a group return
>>> +         * zero on AMD and the highest basic leaf output on others.
>>> +         */
>>> +        unsigned int lvl;
>>> +
>>> +        hvm_cpuid(input & 0xffff0000, &lvl, NULL, NULL, NULL);
>> I have specifically deferred fixing this issue so far, because I don't
>> want to increase the quantity of recursion with hvm_cpuid().
>>
>> Also, because of the poor datastructure for domain cpuid, this adds 1
>> and possibly 2 extra loops over the unordered list.
>>
>>
>> On the way back from Toronto, I started experimenting with my
>> full-policy plans, including a structured information layout so
>> cpuid.basic.max_leaf can be found directly, and starting a guest_cpuid()
>> function intending to replace both pv_cpuid() and hvm_cpuid() in due course.
>>
>> Would you be amenable to leaving this issue as-is for now, until there
>> is a more efficient way of fixing it?
> If you get this ready for 4.8, yes. Otherwise I think the variant here
> is better than nothing until yours arrives.

There is no way it will be done for 4.8.

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] x86: correct CPUID output for out of bounds input
  2016-08-24 15:31 [PATCH] x86: correct CPUID output for out of bounds input Jan Beulich
  2016-09-01 11:23 ` Andrew Cooper
@ 2016-09-01 14:27 ` Andrew Cooper
  2016-09-01 15:27   ` Jan Beulich
  1 sibling, 1 reply; 11+ messages in thread
From: Andrew Cooper @ 2016-09-01 14:27 UTC (permalink / raw)
  To: Jan Beulich, xen-devel

On 24/08/16 16:31, Jan Beulich wrote:
> Another place where we should try to behave like real hardware; see
> the code comments.
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
>
> --- a/xen/arch/x86/hvm/hvm.c
> +++ b/xen/arch/x86/hvm/hvm.c
> @@ -3358,6 +3358,31 @@ void hvm_cpuid(unsigned int input, unsig
>      if ( !edx )
>          edx = &dummy;
>  
> +    if ( input & 0xffff )
> +    {
> +        /*
> +         * Requests beyond the highest supported leaf within a group return
> +         * zero on AMD and the highest basic leaf output on others.
> +         */
> +        unsigned int lvl;
> +
> +        hvm_cpuid(input & 0xffff0000, &lvl, NULL, NULL, NULL);
> +        if ( ((lvl ^ input) >> 16) || input > lvl )

This logic isn't correct.  It doesn't cope in the Intel case when lvl
aliases the upper 16 bits of input, despite input being an unknown group.

When I considered the problem before, the only functioning logic I came
up with was to know that for Intel, input = 0x8000xxxx is the only
special case which doesn't collapse into the highest basic leaf.

> +        {
> +            if ( d->arch.x86_vendor == X86_VENDOR_AMD )
> +            {
> +                *eax = 0;
> +                *ebx = 0;
> +                *ecx = 0;
> +                *edx = 0;
> +                return;
> +            }
> +            if ( input >> 16 )
> +                hvm_cpuid(0, &lvl, NULL, NULL, NULL);

Is this really the right way round?  The AMD method of "reserved always
as zero" is the more sane default to take.

I have looked at the Transmeta and Cyrix CPUID docs, and they are
non-specific as to what reserved means.

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] x86: correct CPUID output for out of bounds input
  2016-09-01 14:27 ` Andrew Cooper
@ 2016-09-01 15:27   ` Jan Beulich
  2016-09-02 15:14     ` Andrew Cooper
  0 siblings, 1 reply; 11+ messages in thread
From: Jan Beulich @ 2016-09-01 15:27 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: xen-devel

>>> On 01.09.16 at 16:27, <andrew.cooper3@citrix.com> wrote:
> On 24/08/16 16:31, Jan Beulich wrote:
>> Another place where we should try to behave like real hardware; see
>> the code comments.
>>
>> Signed-off-by: Jan Beulich <jbeulich@suse.com>
>>
>> --- a/xen/arch/x86/hvm/hvm.c
>> +++ b/xen/arch/x86/hvm/hvm.c
>> @@ -3358,6 +3358,31 @@ void hvm_cpuid(unsigned int input, unsig
>>      if ( !edx )
>>          edx = &dummy;
>>  
>> +    if ( input & 0xffff )
>> +    {
>> +        /*
>> +         * Requests beyond the highest supported leaf within a group return
>> +         * zero on AMD and the highest basic leaf output on others.
>> +         */
>> +        unsigned int lvl;
>> +
>> +        hvm_cpuid(input & 0xffff0000, &lvl, NULL, NULL, NULL);
>> +        if ( ((lvl ^ input) >> 16) || input > lvl )
> 
> This logic isn't correct.  It doesn't cope in the Intel case when lvl
> aliases the upper 16 bits of input, despite input being an unknown group.
> 
> When I considered the problem before, the only functioning logic I came
> up with was to know that for Intel, input = 0x8000xxxx is the only
> special case which doesn't collapse into the highest basic leaf.

If we had followed to Intel model before the extended leaf got
introduced, we'd have been incompatible with the extended leaf.
If ever someone introduces another group, we'd then again be
screwed. Yes, we can follow the Intel model, but I intentionally
tried to make the code more forward compatible.

>> +        {
>> +            if ( d->arch.x86_vendor == X86_VENDOR_AMD )
>> +            {
>> +                *eax = 0;
>> +                *ebx = 0;
>> +                *ecx = 0;
>> +                *edx = 0;
>> +                return;
>> +            }
>> +            if ( input >> 16 )
>> +                hvm_cpuid(0, &lvl, NULL, NULL, NULL);
> 
> Is this really the right way round?  The AMD method of "reserved always
> as zero" is the more sane default to take.

If anything I'd then say let's _always_ follow the AMD model.

> I have looked at the Transmeta and Cyrix CPUID docs, and they are
> non-specific as to what reserved means.

While the Cyrix box I have doesn't stay up long enough anymore
to try out in practice, I do recall that in various aspects they very
closely followed what Intel does. There not being any 64-bit
Transmeta CPUs we support, I don't think we currently care about
their behavior.

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] x86: correct CPUID output for out of bounds input
  2016-09-01 15:27   ` Jan Beulich
@ 2016-09-02 15:14     ` Andrew Cooper
  2016-09-05  6:32       ` Jan Beulich
  0 siblings, 1 reply; 11+ messages in thread
From: Andrew Cooper @ 2016-09-02 15:14 UTC (permalink / raw)
  To: Jan Beulich; +Cc: xen-devel

On 01/09/16 16:27, Jan Beulich wrote:
>
>>> +        {
>>> +            if ( d->arch.x86_vendor == X86_VENDOR_AMD )
>>> +            {
>>> +                *eax = 0;
>>> +                *ebx = 0;
>>> +                *ecx = 0;
>>> +                *edx = 0;
>>> +                return;
>>> +            }
>>> +            if ( input >> 16 )
>>> +                hvm_cpuid(0, &lvl, NULL, NULL, NULL);
>> Is this really the right way round?  The AMD method of "reserved always
>> as zero" is the more sane default to take.
> If anything I'd then say let's _always_ follow the AMD model.

It would certainly be better to default to AMD, and special case others
on an as-needed basis.

Strictly speaking, following the AMD model is compatible with the
"Reserved" nature specified for Intel.

Lets just go with this.

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] x86: correct CPUID output for out of bounds input
  2016-09-02 15:14     ` Andrew Cooper
@ 2016-09-05  6:32       ` Jan Beulich
  2016-09-05  9:43         ` Andrew Cooper
  0 siblings, 1 reply; 11+ messages in thread
From: Jan Beulich @ 2016-09-05  6:32 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: xen-devel

>>> On 02.09.16 at 17:14, <andrew.cooper3@citrix.com> wrote:
> On 01/09/16 16:27, Jan Beulich wrote:
>>
>>>> +        {
>>>> +            if ( d->arch.x86_vendor == X86_VENDOR_AMD )
>>>> +            {
>>>> +                *eax = 0;
>>>> +                *ebx = 0;
>>>> +                *ecx = 0;
>>>> +                *edx = 0;
>>>> +                return;
>>>> +            }
>>>> +            if ( input >> 16 )
>>>> +                hvm_cpuid(0, &lvl, NULL, NULL, NULL);
>>> Is this really the right way round?  The AMD method of "reserved always
>>> as zero" is the more sane default to take.
>> If anything I'd then say let's _always_ follow the AMD model.
> 
> It would certainly be better to default to AMD, and special case others
> on an as-needed basis.
> 
> Strictly speaking, following the AMD model is compatible with the
> "Reserved" nature specified for Intel.
> 
> Lets just go with this.

Done. But before sending v2, just to be clear: The group check
which you also didn't like won't go away. That's because if we didn't
do it, we'd hide all CPUID info outside the basic and extended group,
in particular (in case we run virtualized ourselves) and leaves coming
from the lower level hypervisor (most notably our own ones, if it's
another Xen underneath).

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] x86: correct CPUID output for out of bounds input
  2016-09-05  6:32       ` Jan Beulich
@ 2016-09-05  9:43         ` Andrew Cooper
  2016-09-05  9:51           ` Jan Beulich
  0 siblings, 1 reply; 11+ messages in thread
From: Andrew Cooper @ 2016-09-05  9:43 UTC (permalink / raw)
  To: Jan Beulich; +Cc: xen-devel

On 05/09/16 07:32, Jan Beulich wrote:
>>>> On 02.09.16 at 17:14, <andrew.cooper3@citrix.com> wrote:
>> On 01/09/16 16:27, Jan Beulich wrote:
>>>>> +        {
>>>>> +            if ( d->arch.x86_vendor == X86_VENDOR_AMD )
>>>>> +            {
>>>>> +                *eax = 0;
>>>>> +                *ebx = 0;
>>>>> +                *ecx = 0;
>>>>> +                *edx = 0;
>>>>> +                return;
>>>>> +            }
>>>>> +            if ( input >> 16 )
>>>>> +                hvm_cpuid(0, &lvl, NULL, NULL, NULL);
>>>> Is this really the right way round?  The AMD method of "reserved always
>>>> as zero" is the more sane default to take.
>>> If anything I'd then say let's _always_ follow the AMD model.
>> It would certainly be better to default to AMD, and special case others
>> on an as-needed basis.
>>
>> Strictly speaking, following the AMD model is compatible with the
>> "Reserved" nature specified for Intel.
>>
>> Lets just go with this.
> Done. But before sending v2, just to be clear: The group check
> which you also didn't like won't go away. That's because if we didn't
> do it, we'd hide all CPUID info outside the basic and extended group,
> in particular (in case we run virtualized ourselves) and leaves coming
> from the lower level hypervisor (most notably our own ones, if it's
> another Xen underneath).

Architecturally speaking, it is not ok for any of our guests to be able
to see our hypervisors leaves.

The current call to cpuid_hypervisor_leaves() will clobber information
from the outer hypervisor anyway (although I observe that dom0 running
under Xen under Xen can observe the outer Xen leaves if L1 is configured
with both Xen+Viridian).

I will be fixing this information leakage.  As for these bounds checks,
I would put the checks after the cpuid_hypervisor_leaves() call, and
exclude everything other than the base and extended groups.

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] x86: correct CPUID output for out of bounds input
  2016-09-05  9:43         ` Andrew Cooper
@ 2016-09-05  9:51           ` Jan Beulich
  2016-09-05 10:05             ` Andrew Cooper
  0 siblings, 1 reply; 11+ messages in thread
From: Jan Beulich @ 2016-09-05  9:51 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: xen-devel

>>> On 05.09.16 at 11:43, <andrew.cooper3@citrix.com> wrote:
> On 05/09/16 07:32, Jan Beulich wrote:
>>>>> On 02.09.16 at 17:14, <andrew.cooper3@citrix.com> wrote:
>>> On 01/09/16 16:27, Jan Beulich wrote:
>>>>>> +        {
>>>>>> +            if ( d->arch.x86_vendor == X86_VENDOR_AMD )
>>>>>> +            {
>>>>>> +                *eax = 0;
>>>>>> +                *ebx = 0;
>>>>>> +                *ecx = 0;
>>>>>> +                *edx = 0;
>>>>>> +                return;
>>>>>> +            }
>>>>>> +            if ( input >> 16 )
>>>>>> +                hvm_cpuid(0, &lvl, NULL, NULL, NULL);
>>>>> Is this really the right way round?  The AMD method of "reserved always
>>>>> as zero" is the more sane default to take.
>>>> If anything I'd then say let's _always_ follow the AMD model.
>>> It would certainly be better to default to AMD, and special case others
>>> on an as-needed basis.
>>>
>>> Strictly speaking, following the AMD model is compatible with the
>>> "Reserved" nature specified for Intel.
>>>
>>> Lets just go with this.
>> Done. But before sending v2, just to be clear: The group check
>> which you also didn't like won't go away. That's because if we didn't
>> do it, we'd hide all CPUID info outside the basic and extended group,
>> in particular (in case we run virtualized ourselves) and leaves coming
>> from the lower level hypervisor (most notably our own ones, if it's
>> another Xen underneath).
> 
> Architecturally speaking, it is not ok for any of our guests to be able
> to see our hypervisors leaves.

I'm not convinced, and even less so by the generalization to groups
like the Cyrix/VIA or Transmeta ones. Yes, some of the leaves there
would likely need white listing to be applied just like what we do for
some of the base and extended leaves. But even for those (base
and extended) we don't hide everything (in particular we don't hide
the respective lowest numbered subleaf), and hence I don't see why
we should do so with all of the other groups.

Jan

> The current call to cpuid_hypervisor_leaves() will clobber information
> from the outer hypervisor anyway (although I observe that dom0 running
> under Xen under Xen can observe the outer Xen leaves if L1 is configured
> with both Xen+Viridian).
> 
> I will be fixing this information leakage.  As for these bounds checks,
> I would put the checks after the cpuid_hypervisor_leaves() call, and
> exclude everything other than the base and extended groups.
> 
> ~Andrew




_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] x86: correct CPUID output for out of bounds input
  2016-09-05  9:51           ` Jan Beulich
@ 2016-09-05 10:05             ` Andrew Cooper
  0 siblings, 0 replies; 11+ messages in thread
From: Andrew Cooper @ 2016-09-05 10:05 UTC (permalink / raw)
  To: Jan Beulich; +Cc: xen-devel

On 05/09/16 10:51, Jan Beulich wrote:
>>>> On 05.09.16 at 11:43, <andrew.cooper3@citrix.com> wrote:
>> On 05/09/16 07:32, Jan Beulich wrote:
>>>>>> On 02.09.16 at 17:14, <andrew.cooper3@citrix.com> wrote:
>>>> On 01/09/16 16:27, Jan Beulich wrote:
>>>>>>> +        {
>>>>>>> +            if ( d->arch.x86_vendor == X86_VENDOR_AMD )
>>>>>>> +            {
>>>>>>> +                *eax = 0;
>>>>>>> +                *ebx = 0;
>>>>>>> +                *ecx = 0;
>>>>>>> +                *edx = 0;
>>>>>>> +                return;
>>>>>>> +            }
>>>>>>> +            if ( input >> 16 )
>>>>>>> +                hvm_cpuid(0, &lvl, NULL, NULL, NULL);
>>>>>> Is this really the right way round?  The AMD method of "reserved always
>>>>>> as zero" is the more sane default to take.
>>>>> If anything I'd then say let's _always_ follow the AMD model.
>>>> It would certainly be better to default to AMD, and special case others
>>>> on an as-needed basis.
>>>>
>>>> Strictly speaking, following the AMD model is compatible with the
>>>> "Reserved" nature specified for Intel.
>>>>
>>>> Lets just go with this.
>>> Done. But before sending v2, just to be clear: The group check
>>> which you also didn't like won't go away. That's because if we didn't
>>> do it, we'd hide all CPUID info outside the basic and extended group,
>>> in particular (in case we run virtualized ourselves) and leaves coming
>>> from the lower level hypervisor (most notably our own ones, if it's
>>> another Xen underneath).
>> Architecturally speaking, it is not ok for any of our guests to be able
>> to see our hypervisors leaves.
> I'm not convinced, and even less so by the generalization to groups
> like the Cyrix/VIA or Transmeta ones. Yes, some of the leaves there
> would likely need white listing to be applied just like what we do for
> some of the base and extended leaves. But even for those (base
> and extended) we don't hide everything (in particular we don't hide
> the respective lowest numbered subleaf), and hence I don't see why
> we should do so with all of the other groups.

Xen's handling is still broken (albeit it less than it used to be).  A
guest running under Xen should not be able to find any information not
explicitly controlled by Xen, because information leakage like this
causes problems on migrate, etc.

If at some point in the future we choose to extend the whitelist to
include new groups, that is fine.  However, groups which aren't already
explicitly handled by Xen should be excluded from guest view.

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2016-09-05 10:05 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-08-24 15:31 [PATCH] x86: correct CPUID output for out of bounds input Jan Beulich
2016-09-01 11:23 ` Andrew Cooper
2016-09-01 12:56   ` Jan Beulich
2016-09-01 14:17     ` Andrew Cooper
2016-09-01 14:27 ` Andrew Cooper
2016-09-01 15:27   ` Jan Beulich
2016-09-02 15:14     ` Andrew Cooper
2016-09-05  6:32       ` Jan Beulich
2016-09-05  9:43         ` Andrew Cooper
2016-09-05  9:51           ` Jan Beulich
2016-09-05 10:05             ` Andrew Cooper

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).