[PATCH V3 4/4] tools: Add domsetlaunchsecstate virsh command

Jim Fehlig jfehlig at suse.com
Wed Dec 15 04:46:06 UTC 2021


After attesting a domain with the help of domlaunchsecinfo,
domsetlaunchsecstate can be used to set a secret in the guest
domain's memory prior to running the vcpus.

Signed-off-by: Jim Fehlig <jfehlig at suse.com>
---

Some questions and RFC regarding this patch:

I'm not really fond of the command and function names and would appreciate
suggestions :-).

Also, is reading the secret header and secret from a file sufficient? The
sev-tool 'package_secret' command writes the secret to a file.

Lastly, I'm not sure what sizes to expect for secret and secret header. I
may have overlooked it, but didn't find anything related to the size in the
docs. I've temporarily set it to VSH_MAX_XML_FILE until we know a reasonable
value.

 docs/manpages/virsh.rst |  25 ++++++++++
 tools/virsh-domain.c    | 107 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 132 insertions(+)

diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index e828f7ef68..0700b6e5df 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -2088,6 +2088,31 @@ launch security protection is active. If none is active, no parameters
 will be reported.
 
 
+domsetlaunchsecstate
+--------------------
+
+**Syntax:**
+
+::
+
+   domsetlaunchsecstate domain --secrethdr hdr-filename
+       --secret secret-filename [--set-address address]
+
+Set a launch security secret in the guest's memory. The guest must have a
+launchSecurity type enabled in its configuration and be in a paused state.
+On success, the guest can be transitioned to a running state. On failure,
+the guest should be destroyed.
+
+*--secrethdr* specifies a filename containing the base64-encoded secret header.
+The header includes artifacts needed by the hypervisor firmware to recover the
+plain text of the launch secret. *--secret* specifies the filename containing
+the base64-encoded encrypted launch secret.
+
+The *--set-address* option can be used to specify a physical address within
+the guest's memory to set the secret. If not specified, the address will be
+determined by the hypervisor.
+
+
 dommemstat
 ----------
 
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index c748fe2ba9..57978efef9 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -9570,6 +9570,107 @@ cmdDomLaunchSecInfo(vshControl * ctl, const vshCmd * cmd)
     return ret;
 }
 
+/*
+ * "domsetlaunchsecstate" command
+ */
+static const vshCmdInfo info_domsetlaunchsecstate[] = {
+    {.name = "help",
+     .data = N_("Set domain launch security state")
+    },
+    {.name = "desc",
+     .data = N_("Set a secret in the guest domain's memory")
+    },
+    {.name = NULL}
+};
+
+static const vshCmdOptDef opts_domsetlaunchsecstate[] = {
+    VIRSH_COMMON_OPT_DOMAIN_FULL(0),
+    {.name = "secrethdr",
+     .type = VSH_OT_STRING,
+     .flags = VSH_OFLAG_REQ_OPT,
+     .help = N_("path to file containing the secret header"),
+    },
+    {.name = "secret",
+     .type = VSH_OT_STRING,
+     .flags = VSH_OFLAG_REQ_OPT,
+     .help = N_("path to file containing the secret"),
+    },
+    {.name = "set-address",
+     .type = VSH_OT_INT,
+     .help = N_("physical address within the guest domain's memory to set the secret"),
+    },
+    {.name = NULL}
+};
+
+static bool
+cmdDomSetLaunchSecState(vshControl * ctl, const vshCmd * cmd)
+{
+    g_autoptr(virshDomain) dom = NULL;
+    const char *sechdrfile = NULL;
+    const char *secfile = NULL;
+    g_autofree char *sechdr = NULL;
+    g_autofree char *sec = NULL;
+    unsigned long long setaddr;
+    virTypedParameterPtr params = NULL;
+    int nparams = 0;
+    int maxparams = 0;
+    int rv;
+    bool ret = false;
+
+    if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
+        return false;
+
+    if (vshCommandOptStringReq(ctl, cmd, "secrethdr", &sechdrfile) < 0)
+        return false;
+
+    if (vshCommandOptStringReq(ctl, cmd, "secret", &secfile) < 0)
+        return false;
+
+    if (sechdrfile == NULL || secfile == NULL)
+        return false;
+
+    if (virFileReadAll(sechdrfile, VSH_MAX_XML_FILE, &sechdr) < 0) {
+        vshSaveLibvirtError();
+        return false;
+    }
+
+    if (virFileReadAll(secfile, VSH_MAX_XML_FILE, &sec) < 0) {
+        vshSaveLibvirtError();
+        return false;
+    }
+
+    if (virTypedParamsAddString(&params, &nparams, &maxparams,
+                                VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET_HEADER,
+                                sechdr) < 0)
+        return false;
+
+    if (virTypedParamsAddString(&params, &nparams, &maxparams,
+                                VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET,
+                                sec) < 0)
+        return false;
+
+
+    if ((rv = vshCommandOptULongLong(ctl, cmd, "set-address", &setaddr)) < 0) {
+        return false;
+    } else if (rv > 0) {
+        if (virTypedParamsAddULLong(&params, &nparams, &maxparams,
+                                    VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET_SET_ADDRESS,
+                                    setaddr) < 0)
+            return false;
+    }
+
+    if (virDomainSetLaunchSecurityState(dom, params, nparams, 0) != 0) {
+        vshError(ctl, "%s", _("Unable to set launch security state"));
+        goto cleanup;
+    }
+
+    ret = true;
+
+ cleanup:
+    virTypedParamsFree(params, nparams);
+    return ret;
+}
+
 /*
  * "qemu-monitor-command" command
  */
@@ -14595,6 +14696,12 @@ const vshCmdDef domManagementCmds[] = {
      .info = info_domlaunchsecinfo,
      .flags = 0
     },
+    {.name = "domsetlaunchsecstate",
+     .handler = cmdDomSetLaunchSecState,
+     .opts = opts_domsetlaunchsecstate,
+     .info = info_domsetlaunchsecstate,
+     .flags = 0
+    },
     {.name = "domname",
      .handler = cmdDomname,
      .opts = opts_domname,
-- 
2.34.1





More information about the libvir-list mailing list