[libvirt PATCH 08/12] tools: load CPU count and CPU SKU from libvirt

Daniel P. Berrangé posted 12 patches 3 years, 4 months ago
There is a newer version of this series
[libvirt PATCH 08/12] tools: load CPU count and CPU SKU from libvirt
Posted by Daniel P. Berrangé 3 years, 4 months ago
When validating a SEV-ES guest, we need to know the CPU count and VMSA
state. We can get the CPU count directly from libvirt's guest info. The
VMSA state can be constructed automatically if we query the CPU SKU from
host capabilities XML. Neither of these is secure, however, so this
behaviour is restricted.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
 docs/manpages/virt-qemu-sev-validate.rst |  4 ----
 tools/virt-qemu-sev-validate.py          | 23 +++++++++++++++++++++++
 2 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/docs/manpages/virt-qemu-sev-validate.rst b/docs/manpages/virt-qemu-sev-validate.rst
index 7ba7323e13..fcc13d68c8 100644
--- a/docs/manpages/virt-qemu-sev-validate.rst
+++ b/docs/manpages/virt-qemu-sev-validate.rst
@@ -356,7 +356,6 @@ Validate the measurement of a SEV-ES SMP guest booting from disk:
 
    # virt-dom-sev-validate \
        --insecure \
-       --num-cpus 2 \
        --vmsa-cpu0 vmsa0.bin \
        --vmsa-cpu1 vmsa1.bin \
        --tk this-guest-tk.bin \
@@ -369,9 +368,6 @@ automatically constructed VMSA:
 
    # virt-dom-sev-validate \
        --insecure \
-       --cpu-family 23 \
-       --cpu-model 49 \
-       --cpu-stepping 0 \
        --tk this-guest-tk.bin \
        --domain fedora34x86_64
 
diff --git a/tools/virt-qemu-sev-validate.py b/tools/virt-qemu-sev-validate.py
index 2505aff07f..5da1353e60 100755
--- a/tools/virt-qemu-sev-validate.py
+++ b/tools/virt-qemu-sev-validate.py
@@ -869,6 +869,14 @@ class LibvirtConfidentialVM(ConfidentialVM):
         if self.policy is None:
             self.policy = sevinfo["sev-policy"]
 
+        if self.is_sev_es() and self.num_cpus is None:
+            if secure:
+                raise InsecureUsageException(
+                    "Using CPU count from guest is not secure")
+
+            info = self.dom.info()
+            self.num_cpus = info[3]
+
         if self.firmware is None:
             if remote:
                 raise UnsupportedUsageException(
@@ -914,6 +922,21 @@ class LibvirtConfidentialVM(ConfidentialVM):
                         "Using cmdline string from XML is not secure")
                 self.kernel_table.load_cmdline(cmdlinenodes[0].text)
 
+        capsxml = self.conn.getCapabilities()
+        capsdoc = etree.fromstring(capsxml)
+
+        if self.is_sev_es() and self.vmsa_cpu0 is None:
+            if secure:
+                raise InsecureUsageException(
+                    "Using CPU SKU from capabilities is not secure")
+
+            sig = capsdoc.xpath("/capabilities/host/cpu/signature")
+            if len(sig) == 1:
+                cpu_family = int(sig[0].get("family"))
+                cpu_model = int(sig[0].get("model"))
+                cpu_stepping = int(sig[0].get("stepping"))
+                self.build_vmsas(cpu_family, cpu_model, cpu_stepping)
+
 
 def parse_command_line():
     parser = argparse.ArgumentParser(
-- 
2.37.3

Re: [libvirt PATCH 08/12] tools: load CPU count and CPU SKU from libvirt
Posted by Cole Robinson 3 years, 3 months ago
On 10/7/22 7:43 AM, Daniel P. Berrangé wrote:
> When validating a SEV-ES guest, we need to know the CPU count and VMSA
> state. We can get the CPU count directly from libvirt's guest info. The
> VMSA state can be constructed automatically if we query the CPU SKU from
> host capabilities XML. Neither of these is secure, however, so this
> behaviour is restricted.
> 
> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
> ---
>  docs/manpages/virt-qemu-sev-validate.rst |  4 ----
>  tools/virt-qemu-sev-validate.py          | 23 +++++++++++++++++++++++
>  2 files changed, 23 insertions(+), 4 deletions(-)
> 
> diff --git a/docs/manpages/virt-qemu-sev-validate.rst b/docs/manpages/virt-qemu-sev-validate.rst
> index 7ba7323e13..fcc13d68c8 100644
> --- a/docs/manpages/virt-qemu-sev-validate.rst
> +++ b/docs/manpages/virt-qemu-sev-validate.rst
> @@ -356,7 +356,6 @@ Validate the measurement of a SEV-ES SMP guest booting from disk:
>  
>     # virt-dom-sev-validate \
>         --insecure \
> -       --num-cpus 2 \
>         --vmsa-cpu0 vmsa0.bin \
>         --vmsa-cpu1 vmsa1.bin \
>         --tk this-guest-tk.bin \
> @@ -369,9 +368,6 @@ automatically constructed VMSA:
>  
>     # virt-dom-sev-validate \
>         --insecure \
> -       --cpu-family 23 \
> -       --cpu-model 49 \
> -       --cpu-stepping 0 \
>         --tk this-guest-tk.bin \
>         --domain fedora34x86_64
>  
> diff --git a/tools/virt-qemu-sev-validate.py b/tools/virt-qemu-sev-validate.py
> index 2505aff07f..5da1353e60 100755
> --- a/tools/virt-qemu-sev-validate.py
> +++ b/tools/virt-qemu-sev-validate.py
> @@ -869,6 +869,14 @@ class LibvirtConfidentialVM(ConfidentialVM):
>          if self.policy is None:
>              self.policy = sevinfo["sev-policy"]
>  
> +        if self.is_sev_es() and self.num_cpus is None:
> +            if secure:
> +                raise InsecureUsageException(
> +                    "Using CPU count from guest is not secure")
> +
> +            info = self.dom.info()
> +            self.num_cpus = info[3]
> +
>          if self.firmware is None:
>              if remote:
>                  raise UnsupportedUsageException(
> @@ -914,6 +922,21 @@ class LibvirtConfidentialVM(ConfidentialVM):
>                          "Using cmdline string from XML is not secure")
>                  self.kernel_table.load_cmdline(cmdlinenodes[0].text)
>  
> +        capsxml = self.conn.getCapabilities()
> +        capsdoc = etree.fromstring(capsxml)
> +
> +        if self.is_sev_es() and self.vmsa_cpu0 is None:
> +            if secure:
> +                raise InsecureUsageException(
> +                    "Using CPU SKU from capabilities is not secure")
> +
> +            sig = capsdoc.xpath("/capabilities/host/cpu/signature")
> +            if len(sig) == 1:

If this is missing, I'd make it fatal, libvirtd isn't new enough. Could
happen if talking to a remote machine (or testing the script while f36
fedora libvirtd is running, which I did :) ) . It's going to fail later
anyways.

- Cole

> +                cpu_family = int(sig[0].get("family"))
> +                cpu_model = int(sig[0].get("model"))
> +                cpu_stepping = int(sig[0].get("stepping"))
> +                self.build_vmsas(cpu_family, cpu_model, cpu_stepping)
> +
>  
>  def parse_command_line():
>      parser = argparse.ArgumentParser(

Re: [libvirt PATCH 08/12] tools: load CPU count and CPU SKU from libvirt
Posted by Daniel P. Berrangé 3 years, 3 months ago
On Sun, Oct 16, 2022 at 03:09:43PM -0400, Cole Robinson wrote:
> On 10/7/22 7:43 AM, Daniel P. Berrangé wrote:
> > When validating a SEV-ES guest, we need to know the CPU count and VMSA
> > state. We can get the CPU count directly from libvirt's guest info. The
> > VMSA state can be constructed automatically if we query the CPU SKU from
> > host capabilities XML. Neither of these is secure, however, so this
> > behaviour is restricted.
> > 
> > Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
> > ---
> >  docs/manpages/virt-qemu-sev-validate.rst |  4 ----
> >  tools/virt-qemu-sev-validate.py          | 23 +++++++++++++++++++++++
> >  2 files changed, 23 insertions(+), 4 deletions(-)
> > 
> > diff --git a/docs/manpages/virt-qemu-sev-validate.rst b/docs/manpages/virt-qemu-sev-validate.rst
> > index 7ba7323e13..fcc13d68c8 100644
> > --- a/docs/manpages/virt-qemu-sev-validate.rst
> > +++ b/docs/manpages/virt-qemu-sev-validate.rst
> > @@ -356,7 +356,6 @@ Validate the measurement of a SEV-ES SMP guest booting from disk:
> >  
> >     # virt-dom-sev-validate \
> >         --insecure \
> > -       --num-cpus 2 \
> >         --vmsa-cpu0 vmsa0.bin \
> >         --vmsa-cpu1 vmsa1.bin \
> >         --tk this-guest-tk.bin \
> > @@ -369,9 +368,6 @@ automatically constructed VMSA:
> >  
> >     # virt-dom-sev-validate \
> >         --insecure \
> > -       --cpu-family 23 \
> > -       --cpu-model 49 \
> > -       --cpu-stepping 0 \
> >         --tk this-guest-tk.bin \
> >         --domain fedora34x86_64
> >  
> > diff --git a/tools/virt-qemu-sev-validate.py b/tools/virt-qemu-sev-validate.py
> > index 2505aff07f..5da1353e60 100755
> > --- a/tools/virt-qemu-sev-validate.py
> > +++ b/tools/virt-qemu-sev-validate.py
> > @@ -869,6 +869,14 @@ class LibvirtConfidentialVM(ConfidentialVM):
> >          if self.policy is None:
> >              self.policy = sevinfo["sev-policy"]
> >  
> > +        if self.is_sev_es() and self.num_cpus is None:
> > +            if secure:
> > +                raise InsecureUsageException(
> > +                    "Using CPU count from guest is not secure")
> > +
> > +            info = self.dom.info()
> > +            self.num_cpus = info[3]
> > +
> >          if self.firmware is None:
> >              if remote:
> >                  raise UnsupportedUsageException(
> > @@ -914,6 +922,21 @@ class LibvirtConfidentialVM(ConfidentialVM):
> >                          "Using cmdline string from XML is not secure")
> >                  self.kernel_table.load_cmdline(cmdlinenodes[0].text)
> >  
> > +        capsxml = self.conn.getCapabilities()
> > +        capsdoc = etree.fromstring(capsxml)
> > +
> > +        if self.is_sev_es() and self.vmsa_cpu0 is None:
> > +            if secure:
> > +                raise InsecureUsageException(
> > +                    "Using CPU SKU from capabilities is not secure")
> > +
> > +            sig = capsdoc.xpath("/capabilities/host/cpu/signature")
> > +            if len(sig) == 1:
> 
> If this is missing, I'd make it fatal, libvirtd isn't new enough. Could
> happen if talking to a remote machine (or testing the script while f36
> fedora libvirtd is running, which I did :) ) . It's going to fail later
> anyways.

Makes sense.

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|