]> xenbits.xensource.com Git - libvirt.git/commitdiff
Ensure sanlock socket is labelled with the VM process label
authorDaniel P. Berrange <berrange@redhat.com>
Fri, 24 Jun 2011 14:14:41 +0000 (15:14 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Tue, 28 Jun 2011 15:41:46 +0000 (16:41 +0100)
The libvirt sanlock plugin is intentionally leaking a file
descriptor to QEMU. To enable QEMU to use this FD under
SELinux, it must be labelled correctly. We dont want to use
the svirt_image_t for this, since QEMU must not be allowed
to actually use the FD. So instead we label it with svirt_t
using virSecurityManagerSetProcessFDLabel

* src/locking/domain_lock.c, src/locking/domain_lock.h,
  src/locking/lock_driver.h, src/locking/lock_driver_nop.c,
  src/locking/lock_driver_sanlock.c, src/locking/lock_manager.c,
  src/locking/lock_manager.h: Optionally pass an FD back to
  the hypervisor for security driver labelling
* src/qemu/qemu_process.c: label the lock manager plugin
  FD with the process label

src/locking/domain_lock.c
src/locking/domain_lock.h
src/locking/lock_driver.h
src/locking/lock_driver_nop.c
src/locking/lock_driver_sanlock.c
src/locking/lock_manager.c
src/locking/lock_manager.h
src/qemu/qemu_process.c

index 56b535f2c543cab10355a5dcd69b1cf2858ef768..de1937c9c99997e7f67244bc06cd0e4d015d767a 100644 (file)
@@ -153,7 +153,8 @@ error:
 
 int virDomainLockProcessStart(virLockManagerPluginPtr plugin,
                               virDomainObjPtr dom,
-                              bool paused)
+                              bool paused,
+                              int *fd)
 {
     virLockManagerPtr lock;
     int ret;
@@ -165,7 +166,7 @@ int virDomainLockProcessStart(virLockManagerPluginPtr plugin,
     if (paused)
         flags |= VIR_LOCK_MANAGER_ACQUIRE_REGISTER_ONLY;
 
-    ret = virLockManagerAcquire(lock, NULL, flags);
+    ret = virLockManagerAcquire(lock, NULL, flags, fd);
 
     virLockManagerFree(lock);
 
@@ -198,7 +199,7 @@ int virDomainLockProcessResume(virLockManagerPluginPtr plugin,
     if (!(lock = virDomainLockManagerNew(plugin, dom, true)))
         return -1;
 
-    ret = virLockManagerAcquire(lock, state, 0);
+    ret = virLockManagerAcquire(lock, state, 0, NULL);
     virLockManagerFree(lock);
 
     return ret;
@@ -234,7 +235,7 @@ int virDomainLockDiskAttach(virLockManagerPluginPtr plugin,
     if (virDomainLockManagerAddDisk(lock, disk) < 0)
         goto cleanup;
 
-    if (virLockManagerAcquire(lock, NULL, 0) < 0)
+    if (virLockManagerAcquire(lock, NULL, 0, NULL) < 0)
         goto cleanup;
 
     ret = 0;
@@ -283,7 +284,7 @@ int virDomainLockLeaseAttach(virLockManagerPluginPtr plugin,
     if (virDomainLockManagerAddLease(lock, lease) < 0)
         goto cleanup;
 
-    if (virLockManagerAcquire(lock, NULL, 0) < 0)
+    if (virLockManagerAcquire(lock, NULL, 0, NULL) < 0)
         goto cleanup;
 
     ret = 0;
index 40fadd413ec4728cf67952641f161c533b5a9408..dd35c7c5bf18502690bb4ef8a6431c3ee504b76e 100644 (file)
@@ -28,7 +28,8 @@
 
 int virDomainLockProcessStart(virLockManagerPluginPtr plugin,
                               virDomainObjPtr dom,
-                              bool paused);
+                              bool paused,
+                              int *fd);
 int virDomainLockProcessPause(virLockManagerPluginPtr plugin,
                               virDomainObjPtr dom,
                               char **state);
index 2e71113fc2036fd9a9d103cb4d30911490262d7e..c9fe3683aaa68a5a8111894e139bcda98c514b31 100644 (file)
@@ -214,6 +214,7 @@ typedef int (*virLockDriverAddResource)(virLockManagerPtr man,
  * @manager: the lock manager context
  * @state: the current lock state
  * @flags: optional flags, currently unused
+ * @fd: optional return the leaked FD
  *
  * Start managing resources for the object. This
  * must be called from the PID that represents the
@@ -222,11 +223,17 @@ typedef int (*virLockDriverAddResource)(virLockManagerPtr man,
  * The optional state contains information about the
  * locks previously held for the object.
  *
+ * The file descriptor returned in @fd is one that
+ * is intentionally leaked and should not be closed.
+ * It is returned so that it can be labelled by the
+ * security managers (if required).
+ *
  * Returns 0 on success, or -1 on failure
  */
 typedef int (*virLockDriverAcquire)(virLockManagerPtr man,
                                     const char *state,
-                                    unsigned int flags);
+                                    unsigned int flags,
+                                    int *fd);
 
 /**
  * virLockDriverRelease:
index 36a9083c998ad20ce7c7d2e64e1335b09bf5f526..69a5b3407ed1ee4f545e6a3f7539e750252d2dd1 100644 (file)
@@ -66,9 +66,9 @@ static int virLockManagerNopAddResource(virLockManagerPtr lock ATTRIBUTE_UNUSED,
 
 static int virLockManagerNopAcquire(virLockManagerPtr lock ATTRIBUTE_UNUSED,
                                     const char *state ATTRIBUTE_UNUSED,
-                                    unsigned int flags ATTRIBUTE_UNUSED)
+                                    unsigned int flags ATTRIBUTE_UNUSED,
+                                    int *fd ATTRIBUTE_UNUSED)
 {
-
     return 0;
 }
 
index adead76712557ea89aec89a9cd0cda919d79ebc3..86db5b84d4c7384d50140d96d81df50d386129bc 100644 (file)
@@ -229,7 +229,8 @@ error:
 
 static int virLockManagerSanlockAcquire(virLockManagerPtr lock,
                                         const char *state,
-                                        unsigned int flags)
+                                        unsigned int flags,
+                                        int *fd)
 {
     virLockManagerSanlockPrivatePtr priv = lock->privateData;
     struct sanlk_options *opt;
@@ -349,6 +350,9 @@ static int virLockManagerSanlockAcquire(virLockManagerPtr lock,
         VIR_FREE(res_args);
     }
 
+    if (fd)
+        *fd = sock;
+
     return 0;
 
 error:
index e97c738d7cde5270750e785f9e95abb272fed348..7cd56591201217ed72314575940082048a6c3ed4 100644 (file)
@@ -330,13 +330,17 @@ int virLockManagerAddResource(virLockManagerPtr lock,
 
 int virLockManagerAcquire(virLockManagerPtr lock,
                           const char *state,
-                          unsigned int flags)
+                          unsigned int flags,
+                          int *fd)
 {
-    VIR_DEBUG("lock=%p state='%s' flags=%u", lock, NULLSTR(state), flags);
+    VIR_DEBUG("lock=%p state='%s' flags=%u fd=%p", lock, NULLSTR(state), flags, fd);
 
     CHECK_MANAGER(drvAcquire, -1);
 
-    return lock->driver->drvAcquire(lock, state, flags);
+    if (fd)
+        *fd = -1;
+
+    return lock->driver->drvAcquire(lock, state, flags, fd);
 }
 
 
index 13ad3723d2323e75f9ffd347b572d55c965fc2a0..af91cc6d2d8fbe63e07085e0926f16e014b3e2b1 100644 (file)
@@ -52,7 +52,8 @@ int virLockManagerAddResource(virLockManagerPtr manager,
 
 int virLockManagerAcquire(virLockManagerPtr manager,
                           const char *state,
-                          unsigned int flags);
+                          unsigned int flags,
+                          int *fd);
 int virLockManagerRelease(virLockManagerPtr manager,
                           char **state,
                           unsigned int flags);
index 6f5f581a5f3c6d4e41950d6372e01d3ecc730f34..88a31a3e5453790d500a7b89ec1c7798a8fdbee6 100644 (file)
@@ -2033,6 +2033,7 @@ static int qemuProcessHook(void *data)
 {
     struct qemuProcessHookData *h = data;
     int ret = -1;
+    int fd;
 
     /* Some later calls want pid present */
     h->vm->pid = getpid();
@@ -2041,7 +2042,8 @@ static int qemuProcessHook(void *data)
     if (virDomainLockProcessStart(h->driver->lockManager,
                                   h->vm,
                                   /* QEMU is always pased initially */
-                                  true) < 0)
+                                  true,
+                                  &fd) < 0)
         goto cleanup;
 
     if (qemuProcessLimits(h->driver) < 0)
@@ -2063,10 +2065,16 @@ static int qemuProcessHook(void *data)
     if (qemuProcessInitNumaMemoryPolicy(h->vm) < 0)
         return -1;
 
-    VIR_DEBUG("Setting up security labeling");
+    VIR_DEBUG("Setting up security labelling");
     if (virSecurityManagerSetProcessLabel(h->driver->securityManager, h->vm) < 0)
         goto cleanup;
 
+    if (fd != -1) {
+        VIR_DEBUG("Setting up lock manager FD labelling");
+        if (virSecurityManagerSetProcessFDLabel(h->driver->securityManager, h->vm, fd) < 0)
+            goto cleanup;
+    }
+
     ret = 0;
 
 cleanup: