[libvirt] [PATCH v3 12/14] security: Label the external swtpm with SELinux labels
John Ferlan
jferlan at redhat.com
Tue May 8 21:28:33 UTC 2018
On 05/04/2018 04:21 PM, Stefan Berger wrote:
> In this patch we label the swtpm process with SELinux labels. We give it the
> same label as the QEMU process has. We label its state directory and files
> as well.
>
> The file and process labels now look as follows:
>
> Directory: /var/lib/libvirt/swtpm
>
> [root at localhost swtpm]# ls -lZ
> total 4
> rwx------. 2 tss tss system_u:object_r:svirt_image_t:s0:c254,c932 4096 Apr 5 16:46 testvm
>
> [root at localhost testvm]# ls -lZ
> total 8
> -rw-r--r--. 1 tss tss system_u:object_r:svirt_image_t:s0:c254,c932 3648 Apr 5 16:46 tpm-00.permall
>
> The log in /var/log/swtpm/libvirt/qemu is labeled as follows:
>
> -rw-r--r--. 1 tss tss system_u:object_r:svirt_image_t:s0:c254,c932 2237 Apr 5 16:46 vtpm.log
>
> [root at localhost 485d0004-a48f-436a-8457-8a3b73e28567]# ps auxZ | grep swtpm | grep ctrl | grep -v grep
> system_u:system_r:svirt_t:s0:c254,c932 tss 25664 0.0 0.0 28172 3892 ? Ss 16:57 0:00 /usr/bin/swtpm socket --daemon --ctrl type=unixio,path=/var/run/libvirt/qemu/swtpm/testvm-swtpm.sock,mode=0660 --tpmstate dir=/var/lib/libvirt/swtpm/testvm/tpm1.2 --log file=/var/log/swtpm/libvirt/qemu/testvm-swtpm.log
>
> [root at localhost 485d0004-a48f-436a-8457-8a3b73e28567]# ps auxZ | grep qemu | grep tpm | grep -v grep
> system_u:system_r:svirt_t:s0:c254,c932 qemu 25669 99.0 0.0 3096704 48500 ? Sl 16:57 3:28 /bin/qemu-system-x86_64 [..]
>
> Signed-off-by: Stefan Berger <stefanb at linux.vnet.ibm.com>
> ---
> src/libvirt_private.syms | 1 +
> src/qemu/qemu_extdevice.c | 22 ++++++++++-
> src/security/security_driver.h | 4 ++
> src/security/security_manager.c | 17 +++++++++
> src/security/security_manager.h | 3 ++
> src/security/security_selinux.c | 82 +++++++++++++++++++++++++++++++++++++++++
> src/security/security_stack.c | 19 ++++++++++
> 7 files changed, 147 insertions(+), 1 deletion(-)
>
I think this looks OK - not my specialty 0-) though. I see
security_manager, selinux, etc. and my eyes start glazing over!
Anyway, I assume the reason there's no Restore processing is because
everything is deleted at shutdown, right?
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index e533b95..79b8afa 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -1334,6 +1334,7 @@ virSecurityManagerSetProcessLabel;
> virSecurityManagerSetSavedStateLabel;
> virSecurityManagerSetSocketLabel;
> virSecurityManagerSetTapFDLabel;
> +virSecurityManagerSetTPMLabels;
> virSecurityManagerStackAddNested;
> virSecurityManagerTransactionAbort;
> virSecurityManagerTransactionCommit;
> diff --git a/src/qemu/qemu_extdevice.c b/src/qemu/qemu_extdevice.c
> index f3f337d..eb7220d 100644
> --- a/src/qemu/qemu_extdevice.c
> +++ b/src/qemu/qemu_extdevice.c
> @@ -166,12 +166,32 @@ qemuExtTPMStartEmulator(virQEMUDriverPtr driver,
>
> virCommandSetErrorBuffer(cmd, &errbuf);
>
> - if (virCommandRun(cmd, &exitstatus) < 0 || exitstatus != 0) {
> + if (virSecurityManagerSetTPMLabels(driver->securityManager,
> + def) < 0)
> + goto error;
> +
> + if (virSecurityManagerSetChildProcessLabel(driver->securityManager,
> + def, cmd) < 0)
> + goto error;
> +
> + if (virSecurityManagerPreFork(driver->securityManager) < 0)
> + goto error;
> +
> + /* make sure we run this with the appropriate user */
> + virCommandSetUID(cmd, cfg->swtpm_user);
> + virCommandSetGID(cmd, cfg->swtpm_group);
> +
> + ret = virCommandRun(cmd, &exitstatus);
> +
> + virSecurityManagerPostFork(driver->securityManager);
> +
> + if (ret < 0 || exitstatus != 0) {
> VIR_ERROR("Could not start 'swtpm'. exitstatus: %d\n"
> "stderr: %s\n", exitstatus, errbuf);
> virReportError(VIR_ERR_INTERNAL_ERROR,
> _("Could not start 'swtpm'. exitstatus: %d, "
> "error: %s"), exitstatus, errbuf);
> + ret = -1;
> goto error;
> }
>
> diff --git a/src/security/security_driver.h b/src/security/security_driver.h
> index 95e7c4d..4aa415f 100644
> --- a/src/security/security_driver.h
> +++ b/src/security/security_driver.h
> @@ -149,6 +149,8 @@ typedef int (*virSecurityDomainRestoreChardevLabel) (virSecurityManagerPtr mgr,
> virDomainDefPtr def,
> virDomainChrSourceDefPtr dev_source,
> bool chardevStdioLogd);
> +typedef int (*virSecurityDomainSetTPMLabels) (virSecurityManagerPtr mgr,
> + virDomainDefPtr def);
>
>
> struct _virSecurityDriver {
> @@ -213,6 +215,8 @@ struct _virSecurityDriver {
>
> virSecurityDomainSetChardevLabel domainSetSecurityChardevLabel;
> virSecurityDomainRestoreChardevLabel domainRestoreSecurityChardevLabel;
> +
> + virSecurityDomainSetTPMLabels domainSetSecurityTPMLabels;
> };
>
> virSecurityDriverPtr virSecurityDriverLookup(const char *name,
> diff --git a/src/security/security_manager.c b/src/security/security_manager.c
> index 71f7f59..48777bb 100644
> --- a/src/security/security_manager.c
> +++ b/src/security/security_manager.c
> @@ -1204,3 +1204,20 @@ virSecurityManagerRestoreChardevLabel(virSecurityManagerPtr mgr,
> virReportUnsupportedError();
> return -1;
> }
> +
> +
> +int virSecurityManagerSetTPMLabels(virSecurityManagerPtr mgr,
> + virDomainDefPtr vm)
int
virSecurity...
> +{
> + int ret;
> +
> + if (mgr->drv->domainSetSecurityTPMLabels) {
> + virObjectLock(mgr);
> + ret = mgr->drv->domainSetSecurityTPMLabels(mgr, vm);
> + virObjectUnlock(mgr);
> +
> + return ret;
> + }
> +
> + return 0;
> +}
> diff --git a/src/security/security_manager.h b/src/security/security_manager.h
> index c36a8b4..671f6a8 100644
> --- a/src/security/security_manager.h
> +++ b/src/security/security_manager.h
> @@ -194,4 +194,7 @@ int virSecurityManagerRestoreChardevLabel(virSecurityManagerPtr mgr,
> virDomainChrSourceDefPtr dev_source,
> bool chardevStdioLogd);
>
> +int virSecurityManagerSetTPMLabels(virSecurityManagerPtr mgr,
> + virDomainDefPtr vm);
> +
> #endif /* VIR_SECURITY_MANAGER_H__ */
> diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
> index 17bc07a..42a940b 100644
> --- a/src/security/security_selinux.c
> +++ b/src/security/security_selinux.c
> @@ -3047,6 +3047,86 @@ virSecuritySELinuxDomainSetPathLabel(virSecurityManagerPtr mgr,
> return virSecuritySELinuxSetFilecon(mgr, path, seclabel->imagelabel);
> }
>
2 blank lines
> +/*
> + * _virSecuritySELinuxSetSecurityFileLabels:
> + *
> + * @mgr: the virSecurityManager
> + * @path: path to a directory or a file
> + * @seclabel: the security label
> + *
> + * Set the file labels on the given path; if the path is a directory
> + * we label all files found there, including the directory itself,
> + * otherwise we just label the file.
> + */
> +static int
> +_virSecuritySELinuxSetSecurityFileLabels(virSecurityManagerPtr mgr,
> + const char *path,
> + virSecurityLabelDefPtr seclabel)
> +{
> + int ret = 0;
> + struct dirent *ent;
> + char *filename = NULL;
> + DIR *dir;
> +
> + if ((ret = virSecuritySELinuxSetFilecon(mgr, path, seclabel->imagelabel)))
> + return ret;
> +
> + if (virDirOpen(&dir, path) < 0)
> + return 0;
> +
> + while ((ret = virDirRead(dir, &ent, path)) > 0) {
> + if (ent->d_type != DT_REG)
> + continue;
> +
> + if (virAsprintf(&filename, "%s/%s", path, ent->d_name) < 0) {
> + ret = -1;
> + break;
> + }
> + ret = virSecuritySELinuxSetFilecon(mgr, filename,
> + seclabel->imagelabel);
> + VIR_FREE(filename);
> + if (ret)
if (ret < 0)
Things look reasonable to my untrained eyes - on the next series -
hopefully someone else can poke into this particular patch as well.
John
> + break;
> + }
> + if (ret)
> + virReportSystemError(errno, _("Unable to label files under %s"),
> + path);
> +
> + virDirClose(&dir);
> +
> + return ret;
> +}
> +
> +static int
> +virSecuritySELinuxSetSecurityTPMLabels(virSecurityManagerPtr mgr,
> + virDomainDefPtr def)
> +{
> + int ret = 0;
> + virSecurityLabelDefPtr seclabel;
> +
> + seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
> + if (seclabel == NULL)
> + return 0;
> +
> + switch (def->tpm->type) {
> + case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
> + break;
> + case VIR_DOMAIN_TPM_TYPE_EMULATOR:
> + ret = _virSecuritySELinuxSetSecurityFileLabels(
> + mgr, def->tpm->data.emulator.storagepath,
> + seclabel);
> + if (ret == 0 && def->tpm->data.emulator.logfile)
> + ret = _virSecuritySELinuxSetSecurityFileLabels(
> + mgr, def->tpm->data.emulator.logfile,
> + seclabel);
> + break;
> + case VIR_DOMAIN_TPM_TYPE_LAST:
> + break;
> + }
> +
> + return ret;
> +}
> +
> virSecurityDriver virSecurityDriverSELinux = {
> .privateDataLen = sizeof(virSecuritySELinuxData),
> .name = SECURITY_SELINUX_NAME,
> @@ -3106,4 +3186,6 @@ virSecurityDriver virSecurityDriverSELinux = {
>
> .domainSetSecurityChardevLabel = virSecuritySELinuxSetChardevLabel,
> .domainRestoreSecurityChardevLabel = virSecuritySELinuxRestoreChardevLabel,
> +
> + .domainSetSecurityTPMLabels = virSecuritySELinuxSetSecurityTPMLabels,
> };
> diff --git a/src/security/security_stack.c b/src/security/security_stack.c
> index 9615f9f..7f10ef0 100644
> --- a/src/security/security_stack.c
> +++ b/src/security/security_stack.c
> @@ -760,6 +760,23 @@ virSecurityStackDomainRestoreChardevLabel(virSecurityManagerPtr mgr,
> return rc;
> }
>
> +static int
> +virSecurityStackSetSecurityTPMLabels(virSecurityManagerPtr mgr,
> + virDomainDefPtr vm)
> +{
> + virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
> + virSecurityStackItemPtr item = priv->itemsHead;
> + int rc = 0;
> +
> + for (; item; item = item->next) {
> + if (virSecurityManagerSetTPMLabels(item->securityManager,
> + vm) < 0)
> + rc = -1;
> + }
> +
> + return rc;
> +}
> +
> virSecurityDriver virSecurityDriverStack = {
> .privateDataLen = sizeof(virSecurityStackData),
> .name = "stack",
> @@ -822,4 +839,6 @@ virSecurityDriver virSecurityDriverStack = {
>
> .domainSetSecurityChardevLabel = virSecurityStackDomainSetChardevLabel,
> .domainRestoreSecurityChardevLabel = virSecurityStackDomainRestoreChardevLabel,
> +
> + .domainSetSecurityTPMLabels = virSecurityStackSetSecurityTPMLabels,
> };
>
More information about the libvir-list
mailing list