[libvirt PATCH v3 09/10] src: elevate current identity privilege when fetching secret

Daniel P. Berrangé berrange at redhat.com
Wed May 12 13:33:55 UTC 2021


When fetching the value of a private secret, we need to use an elevated
identity otherwise the secret driver will deny access.

When using the modular daemons, the elevated identity needs to be active
before the secret driver connection is opened, and it will apply to all
APIs calls made on that conncetion.

When using the monolithic daemon, the identity at time of opening the
connection is ignored, and the elevated identity needs to be active
precisely at the time the virSecretGetValue API call is made.

After acquiring the secret value, the elevated identity should be
cleared.

This sounds complex, but is fairly straightfoward with the automatic
cleanup callbacks.

Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
---
 src/libxl/libxl_conf.c                     |  5 +++++
 src/qemu/qemu_domain.c                     | 11 ++++++++++-
 src/qemu/qemu_tpm.c                        |  5 +++++
 src/storage/storage_backend_iscsi.c        |  5 +++++
 src/storage/storage_backend_iscsi_direct.c |  5 +++++
 src/storage/storage_backend_rbd.c          |  5 +++++
 src/storage/storage_util.c                 |  5 +++++
 tests/qemuxml2argvmock.c                   |  9 +++++++++
 tests/qemuxml2argvtest.c                   |  6 ++++++
 9 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 4de2158bea..e33297a9ba 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -31,6 +31,7 @@
 #include "datatypes.h"
 #include "virconf.h"
 #include "virfile.h"
+#include "viridentity.h"
 #include "virstring.h"
 #include "viralloc.h"
 #include "viruuid.h"
@@ -1001,6 +1002,10 @@ libxlMakeNetworkDiskSrc(virStorageSource *src, char **srcstr)
     if (src->auth && src->protocol == VIR_STORAGE_NET_PROTOCOL_RBD) {
         g_autofree uint8_t *secret = NULL;
         size_t secretlen = 0;
+        VIR_IDENTITY_AUTORESTORE virIdentity *oldident = virIdentityElevateCurrent();
+
+        if (!oldident)
+            goto cleanup;
 
         username = src->auth->username;
         if (!(conn = virConnectOpen("xen:///system")))
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index fe56d17486..10641846b3 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -41,6 +41,7 @@
 #include "viralloc.h"
 #include "virlog.h"
 #include "virerror.h"
+#include "viridentity.h"
 #include "cpu/cpu.h"
 #include "viruuid.h"
 #include "virfile.h"
@@ -1116,9 +1117,13 @@ qemuDomainSecretPlainSetup(qemuDomainSecretInfo *secinfo,
                            const char *username,
                            virSecretLookupTypeDef *seclookupdef)
 {
+    VIR_IDENTITY_AUTORESTORE virIdentity *oldident = virIdentityElevateCurrent();
     g_autoptr(virConnect) conn = virGetConnectSecret();
     int ret = -1;
 
+    if (!oldident)
+        return -1;
+
     if (!conn)
         return -1;
 
@@ -1213,11 +1218,15 @@ qemuDomainSecretAESSetupFromSecret(qemuDomainObjPrivate *priv,
                                    const char *username,
                                    virSecretLookupTypeDef *seclookupdef)
 {
-    g_autoptr(virConnect) conn = virGetConnectSecret();
     qemuDomainSecretInfo *secinfo;
     g_autofree char *alias = qemuAliasForSecret(srcalias, secretuse);
     g_autofree uint8_t *secret = NULL;
     size_t secretlen = 0;
+    VIR_IDENTITY_AUTORESTORE virIdentity *oldident = virIdentityElevateCurrent();
+    g_autoptr(virConnect) conn = virGetConnectSecret();
+
+    if (!oldident)
+        return NULL;
 
     if (!conn)
         return NULL;
diff --git a/src/qemu/qemu_tpm.c b/src/qemu/qemu_tpm.c
index 9ae7e5f94b..477a26dc69 100644
--- a/src/qemu/qemu_tpm.c
+++ b/src/qemu/qemu_tpm.c
@@ -33,6 +33,7 @@
 #include "vircommand.h"
 #include "viralloc.h"
 #include "virkmod.h"
+#include "viridentity.h"
 #include "virlog.h"
 #include "virutil.h"
 #include "viruuid.h"
@@ -366,6 +367,10 @@ qemuTPMSetupEncryption(const unsigned char *secretuuid,
     virSecretLookupTypeDef seclookupdef = {
          .type = VIR_SECRET_LOOKUP_TYPE_UUID,
     };
+    VIR_IDENTITY_AUTORESTORE virIdentity *oldident = virIdentityElevateCurrent();
+
+    if (!oldident)
+        return -1;
 
     conn = virGetConnectSecret();
     if (!conn)
diff --git a/src/storage/storage_backend_iscsi.c b/src/storage/storage_backend_iscsi.c
index 67e59e856c..ed17ed11a6 100644
--- a/src/storage/storage_backend_iscsi.c
+++ b/src/storage/storage_backend_iscsi.c
@@ -34,6 +34,7 @@
 #include "virerror.h"
 #include "virfile.h"
 #include "viriscsi.h"
+#include "viridentity.h"
 #include "virlog.h"
 #include "virobject.h"
 #include "virstring.h"
@@ -263,6 +264,7 @@ virStorageBackendISCSISetAuth(const char *portal,
     virStorageAuthDef *authdef = source->auth;
     int ret = -1;
     virConnectPtr conn = NULL;
+    VIR_IDENTITY_AUTORESTORE virIdentity *oldident = NULL;
 
     if (!authdef || authdef->authType == VIR_STORAGE_AUTH_TYPE_NONE)
         return 0;
@@ -275,6 +277,9 @@ virStorageBackendISCSISetAuth(const char *portal,
         return -1;
     }
 
+    if (!(oldident = virIdentityElevateCurrent()))
+        return -1;
+
     conn = virGetConnectSecret();
     if (!conn)
         return -1;
diff --git a/src/storage/storage_backend_iscsi_direct.c b/src/storage/storage_backend_iscsi_direct.c
index cb5b39baf4..0bff1882b9 100644
--- a/src/storage/storage_backend_iscsi_direct.c
+++ b/src/storage/storage_backend_iscsi_direct.c
@@ -29,6 +29,7 @@
 #include "storage_util.h"
 #include "viralloc.h"
 #include "virerror.h"
+#include "viridentity.h"
 #include "virlog.h"
 #include "virobject.h"
 #include "virstring.h"
@@ -94,6 +95,7 @@ virStorageBackendISCSIDirectSetAuth(struct iscsi_context *iscsi,
     virStorageAuthDef *authdef = source->auth;
     int ret = -1;
     virConnectPtr conn = NULL;
+    VIR_IDENTITY_AUTORESTORE virIdentity *oldident = NULL;
 
     if (!authdef || authdef->authType == VIR_STORAGE_AUTH_TYPE_NONE)
         return 0;
@@ -107,6 +109,9 @@ virStorageBackendISCSIDirectSetAuth(struct iscsi_context *iscsi,
         return ret;
     }
 
+    if (!(oldident = virIdentityElevateCurrent()))
+        return -1;
+
     if (!(conn = virGetConnectSecret()))
         return ret;
 
diff --git a/src/storage/storage_backend_rbd.c b/src/storage/storage_backend_rbd.c
index 9fbb2464d1..ce3ab11dd6 100644
--- a/src/storage/storage_backend_rbd.c
+++ b/src/storage/storage_backend_rbd.c
@@ -27,6 +27,7 @@
 #include "storage_backend_rbd.h"
 #include "storage_conf.h"
 #include "viralloc.h"
+#include "viridentity.h"
 #include "virlog.h"
 #include "viruuid.h"
 #include "virstring.h"
@@ -196,6 +197,7 @@ virStorageBackendRBDOpenRADOSConn(virStorageBackendRBDState *ptr,
     g_autofree char *mon_buff = NULL;
 
     if (authdef) {
+        VIR_IDENTITY_AUTORESTORE virIdentity *oldident = NULL;
         g_autofree char *rados_key = NULL;
         int rc;
 
@@ -206,6 +208,9 @@ virStorageBackendRBDOpenRADOSConn(virStorageBackendRBDState *ptr,
             goto cleanup;
         }
 
+        if (!(oldident = virIdentityElevateCurrent()))
+            goto cleanup;
+
         conn = virGetConnectSecret();
         if (!conn)
             return -1;
diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c
index 7efadc2197..2b0d08c65d 100644
--- a/src/storage/storage_util.c
+++ b/src/storage/storage_util.c
@@ -68,6 +68,7 @@
 #include "storage_source_conf.h"
 #include "virlog.h"
 #include "virfile.h"
+#include "viridentity.h"
 #include "virjson.h"
 #include "virqemu.h"
 #include "virstring.h"
@@ -1265,6 +1266,7 @@ storageBackendCreateQemuImgSecretPath(virStoragePoolObj *pool,
     size_t secretlen = 0;
     virConnectPtr conn = NULL;
     VIR_AUTOCLOSE fd = -1;
+    VIR_IDENTITY_AUTORESTORE virIdentity *oldident = NULL;
 
     if (!enc) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -1279,6 +1281,9 @@ storageBackendCreateQemuImgSecretPath(virStoragePoolObj *pool,
         return NULL;
     }
 
+    if (!(oldident = virIdentityElevateCurrent()))
+        return NULL;
+
     conn = virGetConnectSecret();
     if (!conn)
         return NULL;
diff --git a/tests/qemuxml2argvmock.c b/tests/qemuxml2argvmock.c
index 77a0814c08..2265492f1e 100644
--- a/tests/qemuxml2argvmock.c
+++ b/tests/qemuxml2argvmock.c
@@ -18,10 +18,13 @@
 
 #include <config.h>
 
+#define LIBVIRT_VIRIDENTITYPRIV_H_ALLOW
+
 #include "internal.h"
 #include "viralloc.h"
 #include "vircommand.h"
 #include "vircrypto.h"
+#include "viridentitypriv.h"
 #include "virmock.h"
 #include "virlog.h"
 #include "virnetdev.h"
@@ -292,3 +295,9 @@ qemuInterfaceVDPAConnect(virDomainNetDef *net G_GNUC_UNUSED)
         abort();
     return 1732;
 }
+
+char *
+virIdentityEnsureSystemToken(void)
+{
+    return g_strdup("3de80bcbf22d4833897f1638e01be9b2");
+}
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index a9dafe226e..a93d21d61a 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -11,6 +11,7 @@
 
 # include "internal.h"
 # include "viralloc.h"
+# include "viridentity.h"
 # include "qemu/qemu_alias.h"
 # include "qemu/qemu_capabilities.h"
 # include "qemu/qemu_command.h"
@@ -650,6 +651,7 @@ testCompareXMLToArgv(const void *data)
     xmlNodePtr root;
     g_autofree char *archstr = NULL;
     virArch arch = VIR_ARCH_NONE;
+    g_autoptr(virIdentity) sysident = virIdentityGetSystem();
 
     if (info->arch != VIR_ARCH_NONE && info->arch != VIR_ARCH_X86_64)
         qemuTestSetHostArch(&driver, info->arch);
@@ -670,6 +672,9 @@ testCompareXMLToArgv(const void *data)
     virSetConnectSecret(conn);
     virSetConnectStorage(conn);
 
+    if (virIdentitySetCurrent(sysident) < 0)
+        goto cleanup;
+
     if (testCheckExclusiveFlags(info->flags) < 0)
         goto cleanup;
 
@@ -809,6 +814,7 @@ testCompareXMLToArgv(const void *data)
     VIR_FREE(log);
     virDomainChrSourceDefClear(&monitor_chr);
     virObjectUnref(vm);
+    virIdentitySetCurrent(NULL);
     virSetConnectSecret(NULL);
     virSetConnectStorage(NULL);
     if (info->arch != VIR_ARCH_NONE && info->arch != VIR_ARCH_X86_64)
-- 
2.31.1




More information about the libvir-list mailing list