]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
src: elevate current identity privilege when fetching secret
authorDaniel P. Berrangé <berrange@redhat.com>
Fri, 7 May 2021 15:53:40 +0000 (16:53 +0100)
committerDaniel P. Berrangé <berrange@redhat.com>
Thu, 13 May 2021 10:07:43 +0000 (11:07 +0100)
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.

Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
src/libxl/libxl_conf.c
src/qemu/qemu_domain.c
src/qemu/qemu_tpm.c
src/storage/storage_backend_iscsi.c
src/storage/storage_backend_iscsi_direct.c
src/storage/storage_backend_rbd.c
src/storage/storage_util.c
tests/qemuxml2argvmock.c
tests/qemuxml2argvtest.c

index 4de2158bea45f448840abd6f470e895d1e85f717..e33297a9bad6566428dd84b37e5f661a80099296 100644 (file)
@@ -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")))
index fe56d1748674c865a76ed2d17da10638f146fb59..10641846b34cba03a049b729107c2f16e78c31ad 100644 (file)
@@ -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;
index 9ae7e5f94bd7db7b1cd4fcab8b39a2404cf0c4e1..477a26dc69211904ef955af7cfe9e518e2905657 100644 (file)
@@ -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)
index 67e59e856ccc028302a7d1e1bd00a37604818c34..ed17ed11a6bf61b26b5ebcd6878bb5a31dfd6d27 100644 (file)
@@ -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;
index cb5b39baf421e65f7a67fd5ef388d101cbc4174f..0bff1882b9da368b629fab51f74be0b6d7cba66c 100644 (file)
@@ -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;
 
index 9fbb2464d10907db2b8a461149157b915fa3a3a1..ce3ab11dd68d51943031b5dcd5549f4884175e62 100644 (file)
@@ -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;
index 7efadc219769cbd59da70d587afd4e03c482d62f..2b0d08c65d7f74b78daf69129326384be9665fdf 100644 (file)
@@ -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;
index 77a0814c08b6fc812c7ea0df244b5bd0d88c103a..2265492f1e99df3879803fc368be798683c51c02 100644 (file)
 
 #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");
+}
index a9dafe226eeb658392b324422a72088e84f4050c..a93d21d61a9f2f41a9960fd4b16de323a27543c6 100644 (file)
@@ -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)