]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
security: Introduce virSecurityManagerDomainSetPathLabelRO
authorMichal Privoznik <mprivozn@redhat.com>
Fri, 3 Apr 2020 12:31:35 +0000 (14:31 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 17 Apr 2020 14:24:30 +0000 (16:24 +0200)
This API allows drivers to separate out handling of @stdin_path
of virSecurityManagerSetAllLabel(). The thing is, the QEMU driver
uses transactions for virSecurityManagerSetAllLabel() which
relabels devices from inside of domain's namespace. This is what
we usually want. Except when resuming domain from a file. The
file is opened before any namespace is set up and the FD is
passed to QEMU to read the migration stream from. Because of
this, the file lives outside of the namespace and if it so
happens that the file is a block device (i.e. it lives under
/dev) its copy will be created in the namespace. But the FD that
is passed to QEMU points to the original living in the host and
not in the namespace. So relabeling the file inside the namespace
helps nothing.

But if we have a separate API for relabeling the restore file
then the QEMU driver can continue calling
virSecurityManagerSetAllLabel() with transactions enabled and
call this new API without transactions.

We already have an API for relabeling a single file
(virSecurityManagerDomainSetPathLabel()) but in case of SELinux
it uses @imagelabel (which allows RW access) and we want to use
@content_context (which allows RO access).

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Erik Skultety <eskultet@redhat.com>
src/libvirt_private.syms
src/security/security_driver.h
src/security/security_manager.c
src/security/security_manager.h
src/security/security_stack.c

index ec367653d5a824691d210da9b880c8680134a8a5..182a570382df8aef1a5c439b5f1bce576bfc881f 100644 (file)
@@ -1525,6 +1525,7 @@ virSecurityDriverLookup;
 virSecurityManagerCheckAllLabel;
 virSecurityManagerClearSocketLabel;
 virSecurityManagerDomainSetPathLabel;
+virSecurityManagerDomainSetPathLabelRO;
 virSecurityManagerGenLabel;
 virSecurityManagerGetBaseLabel;
 virSecurityManagerGetDOI;
index 33539558138d828c39d6af1de2c3de30cc4b30a4..d23b64668d84b9901f8842f9ef733bfc664f4323 100644 (file)
@@ -140,6 +140,9 @@ typedef int (*virSecurityDomainSetPathLabel) (virSecurityManagerPtr mgr,
                                               virDomainDefPtr def,
                                               const char *path,
                                               bool allowSubtree);
+typedef int (*virSecurityDomainSetPathLabelRO) (virSecurityManagerPtr mgr,
+                                                virDomainDefPtr def,
+                                                const char *path);
 typedef int (*virSecurityDomainSetChardevLabel) (virSecurityManagerPtr mgr,
                                                  virDomainDefPtr def,
                                                  virDomainChrSourceDefPtr dev_source,
@@ -211,6 +214,7 @@ struct _virSecurityDriver {
     virSecurityDriverGetBaseLabel getBaseLabel;
 
     virSecurityDomainSetPathLabel domainSetPathLabel;
+    virSecurityDomainSetPathLabelRO domainSetPathLabelRO;
 
     virSecurityDomainSetChardevLabel domainSetSecurityChardevLabel;
     virSecurityDomainRestoreChardevLabel domainRestoreSecurityChardevLabel;
index fe032746fff8445ad2a702e28707ef8ccbfa0faa..6bf297470ce4b9ba6f4d5a3276a61c8b56e5582a 100644 (file)
@@ -1077,6 +1077,35 @@ virSecurityManagerDomainSetPathLabel(virSecurityManagerPtr mgr,
 }
 
 
+/**
+ * virSecurityManagerDomainSetPathLabelRO:
+ * @mgr: security manager object
+ * @vm: domain definition object
+ * @path: path to label
+ *
+ * This function relabels given @path for read only access, which
+ * is in contrast with virSecurityManagerDomainSetPathLabel() which
+ * gives read write access.
+ *
+ * Returns: 0 on success, -1 on error.
+ */
+int
+virSecurityManagerDomainSetPathLabelRO(virSecurityManagerPtr mgr,
+                                       virDomainDefPtr vm,
+                                       const char *path)
+{
+    if (mgr->drv->domainSetPathLabelRO) {
+        int ret;
+        virObjectLock(mgr);
+        ret = mgr->drv->domainSetPathLabelRO(mgr, vm, path);
+        virObjectUnlock(mgr);
+        return ret;
+    }
+
+    return 0;
+}
+
+
 /**
  * virSecurityManagerSetMemoryLabel:
  * @mgr: security manager object
index 7699bcbc6fb0765978210dd4303539741ddd75ef..2c5fa3ee15b7d45e22719f31222b2e70ade8e7d1 100644 (file)
@@ -189,6 +189,10 @@ int virSecurityManagerDomainSetPathLabel(virSecurityManagerPtr mgr,
                                          const char *path,
                                          bool allowSubtree);
 
+int virSecurityManagerDomainSetPathLabelRO(virSecurityManagerPtr mgr,
+                                           virDomainDefPtr vm,
+                                           const char *path);
+
 int virSecurityManagerSetChardevLabel(virSecurityManagerPtr mgr,
                                       virDomainDefPtr def,
                                       virDomainChrSourceDefPtr dev_source,
index 073876daffb5ab48a8c0ea9c7436eb177bd475b7..165303a1f8e965a35ed44c551fe61a0db1dec7f0 100644 (file)
@@ -825,6 +825,26 @@ virSecurityStackDomainSetPathLabel(virSecurityManagerPtr mgr,
     return rc;
 }
 
+
+static int
+virSecurityStackDomainSetPathLabelRO(virSecurityManagerPtr mgr,
+                                     virDomainDefPtr vm,
+                                     const char *path)
+{
+    virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+    virSecurityStackItemPtr item = priv->itemsHead;
+    int rc = 0;
+
+    for (; item; item = item->next) {
+        if (virSecurityManagerDomainSetPathLabelRO(item->securityManager,
+                                                   vm, path) < 0)
+            rc = -1;
+    }
+
+    return rc;
+}
+
+
 static int
 virSecurityStackDomainSetChardevLabel(virSecurityManagerPtr mgr,
                                       virDomainDefPtr def,
@@ -985,6 +1005,7 @@ virSecurityDriver virSecurityDriverStack = {
     .getBaseLabel                       = virSecurityStackGetBaseLabel,
 
     .domainSetPathLabel                 = virSecurityStackDomainSetPathLabel,
+    .domainSetPathLabelRO               = virSecurityStackDomainSetPathLabelRO,
 
     .domainSetSecurityChardevLabel      = virSecurityStackDomainSetChardevLabel,
     .domainRestoreSecurityChardevLabel  = virSecurityStackDomainRestoreChardevLabel,