All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Daniel P. Berrangé" <berrange@redhat.com>
To: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Cc: thomas.lendacky@amd.com, brijesh.singh@amd.com,
	jejb@linux.ibm.com, tobin@ibm.com, qemu-devel@nongnu.org,
	Tobin Feldman-Fitzthum <tobin@linux.vnet.ibm.com>,
	pbonzini@redhat.com
Subject: Re: [PATCH v3] SEV: QMP support for Inject-Launch-Secret
Date: Mon, 12 Oct 2020 17:49:52 +0100	[thread overview]
Message-ID: <20201012164952.GK39408@redhat.com> (raw)
In-Reply-To: <20201012161941.GI6677@work-vm>

On Mon, Oct 12, 2020 at 05:21:15PM +0100, Dr. David Alan Gilbert wrote:
> * Tobin Feldman-Fitzthum (tobin@linux.vnet.ibm.com) wrote:
> > AMD SEV allows a guest owner to inject a secret blob
> > into the memory of a virtual machine. The secret is
> > encrypted with the SEV Transport Encryption Key and
> > integrity is guaranteed with the Transport Integrity
> > Key. Although QEMU faciliates the injection of the

Trivial typo  s/faciliates/facilitates/

> > launch secret, it cannot access the secret.
> > 
> > Signed-off-by: Tobin Feldman-Fitzthum <tobin@linux.vnet.ibm.com>
> > ---
> >  include/monitor/monitor.h |  3 ++
> >  include/sysemu/sev.h      |  2 ++
> >  monitor/misc.c            |  8 ++---
> >  qapi/misc-target.json     | 18 +++++++++++
> >  target/i386/monitor.c     |  9 ++++++
> >  target/i386/sev-stub.c    |  5 +++
> >  target/i386/sev.c         | 66 +++++++++++++++++++++++++++++++++++++++
> >  target/i386/trace-events  |  1 +
> >  8 files changed, 108 insertions(+), 4 deletions(-)


> > diff --git a/qapi/misc-target.json b/qapi/misc-target.json
> > index dee3b45930..d145f916b3 100644
> > --- a/qapi/misc-target.json
> > +++ b/qapi/misc-target.json
> > @@ -200,6 +200,24 @@
> >  { 'command': 'query-sev-capabilities', 'returns': 'SevCapability',
> >    'if': 'defined(TARGET_I386)' }
> >  
> > +##
> > +# @sev-inject-launch-secret:
> > +#
> > +# This command injects a secret blob into memory of SEV guest.
> > +#
> > +# @packet-header: the launch secret packet header encoded in base64
> > +#
> > +# @secret: the launch secret data to be injected encoded in base64

Just to double check, this "secret" is /not/ in clear text, so there's
no way either QEMU nor the QMP client can access sensitive info, right ?

If 'secret' was clear text, then we would need to pass the data across
QMP in a different way.

> > +#
> > +# @gpa: the guest physical address where secret will be injected.
> > +#
> > +# Since: 5.1

s/5.1/5.2/

> > +#
> > +##
> > +{ 'command': 'sev-inject-launch-secret',
> > +  'data': { 'packet-header': 'str', 'secret': 'str', 'gpa': 'uint64' },
> > +  'if': 'defined(TARGET_I386)' }
> > +
> >  ##
> >  # @dump-skeys:
> >  #
> > diff --git a/target/i386/monitor.c b/target/i386/monitor.c
> > index 27ebfa3ad2..42bcfe6dc0 100644
> > --- a/target/i386/monitor.c
> > +++ b/target/i386/monitor.c
> > @@ -736,3 +736,12 @@ SevCapability *qmp_query_sev_capabilities(Error **errp)
> >  
> >      return data;
> >  }
> > +
> > +void qmp_sev_inject_launch_secret(const char *packet_hdr,
> > +                                  const char *secret, uint64_t gpa,
> > +                                  Error **errp)
> > +{
> > +    if (sev_inject_launch_secret(packet_hdr, secret, gpa) != 0) {
> > +        error_setg(errp, "SEV inject secret failed");

This generic error message is useless - sev_inject_launch_secret() needs
to take the 'errp' parameter and report what actually failed.

> > +    }
> > +}
> > diff --git a/target/i386/sev-stub.c b/target/i386/sev-stub.c
> > index e5ee13309c..fed4588185 100644
> > --- a/target/i386/sev-stub.c
> > +++ b/target/i386/sev-stub.c
> > @@ -48,3 +48,8 @@ SevCapability *sev_get_capabilities(void)
> >  {
> >      return NULL;
> >  }
> > +int sev_inject_launch_secret(const char *hdr, const char *secret,
> > +                             uint64_t gpa)
> > +{
> > +    return 1;
> > +}
> > diff --git a/target/i386/sev.c b/target/i386/sev.c
> > index d273174ad3..cbeb8f2e02 100644
> > --- a/target/i386/sev.c
> > +++ b/target/i386/sev.c
> > @@ -28,6 +28,8 @@
> >  #include "sysemu/runstate.h"
> >  #include "trace.h"
> >  #include "migration/blocker.h"
> > +#include "exec/address-spaces.h"
> > +#include "monitor/monitor.h"
> >  
> >  #define TYPE_SEV_GUEST "sev-guest"
> >  #define SEV_GUEST(obj)                                          \
> > @@ -769,6 +771,70 @@ sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len)
> >      return 0;
> >  }
> >  
> > +int sev_inject_launch_secret(const char *packet_hdr,
> > +                             const char *secret, uint64_t gpa)
> > +{
> > +    struct kvm_sev_launch_secret input;
> > +    guchar *data = NULL, *hdr = NULL;

If you declare with  'g_autofree' you don't need the manual 'g_free'
calls later. This in turn means you can get rid of the "goto err"
jumps and instead directly return.

> > +    int error, ret = 1;
> > +    void *hva;
> > +    gsize hdr_sz = 0, data_sz = 0;
> > +    Error *local_err = NULL;

Declare with

   g_autoptr(Error) local_err = NULL

to fix the leak David mentions


> > +    MemoryRegion *mr = NULL;
> > +
> > +    /* secret can be inject only in this state */
> > +    if (!sev_check_state(sev_guest, SEV_STATE_LAUNCH_SECRET)) {
> > +        error_report("SEV: Not in correct state. (LSECRET) %x",
> > +                     sev_guest->state);
> > +        return 1;
> > +    }
> > +
> > +    hdr = g_base64_decode(packet_hdr, &hdr_sz);
> > +    if (!hdr || !hdr_sz) {
> > +        error_report("SEV: Failed to decode sequence header");
> > +        return 1;
> > +    }
> > +
> > +    data = g_base64_decode(secret, &data_sz);
> > +    if (!data || !data_sz) {
> > +        error_report("SEV: Failed to decode data");
> > +        goto err;
> > +    }
> > +
> > +    hva = gpa2hva(&mr, gpa, data_sz, &local_err);
> > +    if (!hva) {
> > +        error_report("SEV: Failed to calculate guest address.");
> 
> Note this is leaking local_err; you need to turn that into probably an
>   error_reportf_err(local_err, "SEV: Failed to calculate guest address:");

Actually this method needs to take an "Error **errp" parameter, so that the
error is propagated back to the QMP command handler, and from there
back to the client app.

> Also the '5.1' above needs to change to 5.2.
> 
> I think with that it looks OK to me.

> > +        goto err;
> > +    }
> > +
> > +    input.hdr_uaddr = (uint64_t)(unsigned long)hdr;
> > +    input.hdr_len = hdr_sz;
> > +
> > +    input.trans_uaddr = (uint64_t)(unsigned long)data;
> > +    input.trans_len = data_sz;
> > +
> > +    input.guest_uaddr = (uint64_t)(unsigned long)hva;
> > +    input.guest_len = data_sz;
> > +
> > +    trace_kvm_sev_launch_secret(gpa, input.guest_uaddr,
> > +                                input.trans_uaddr, input.trans_len);
> > +
> > +    ret = sev_ioctl(sev_guest->sev_fd, KVM_SEV_LAUNCH_SECRET,
> > +                    &input, &error);
> > +    if (ret) {
> > +        error_report("SEV: failed to inject secret ret=%d fw_error=%d '%s'",
> > +                     ret, error, fw_error_to_str(error));
> > +        goto err;
> > +    }
> > +
> > +    ret = 0;
> > +
> > +err:
> > +    g_free(data);
> > +    g_free(hdr);
> > +    return ret;
> > +}


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 :|



  reply	other threads:[~2020-10-12 16:52 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-06 21:54 [PATCH v3] SEV: QMP support for Inject-Launch-Secret Tobin Feldman-Fitzthum
2020-07-06 22:00 ` tobin
2020-09-21 19:16 ` Dr. David Alan Gilbert
2020-09-21 20:33   ` Tobin Feldman-Fitzthum
2020-09-21 22:14     ` Tom Lendacky
2020-10-12 15:57     ` Dr. David Alan Gilbert
2020-10-12 16:00       ` James Bottomley
2020-10-12 16:38         ` Dr. David Alan Gilbert
2020-10-12 16:21 ` Dr. David Alan Gilbert
2020-10-12 16:49   ` Daniel P. Berrangé [this message]
2020-10-13 21:56     ` tobin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201012164952.GK39408@redhat.com \
    --to=berrange@redhat.com \
    --cc=brijesh.singh@amd.com \
    --cc=dgilbert@redhat.com \
    --cc=jejb@linux.ibm.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=thomas.lendacky@amd.com \
    --cc=tobin@ibm.com \
    --cc=tobin@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.