summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel P. Berrange <berrange@redhat.com>2011-06-24 15:14:41 +0100
committerDaniel P. Berrange <berrange@redhat.com>2011-06-28 16:41:46 +0100
commit5247b0695a1914e16d1b6333aff6038c0bd578dc (patch)
tree28d0783556a2a624bd7ffc30fc0179e538733ee2
parentAdd a virSecurityManagerSetProcessFDLabel (diff)
downloadlibvirt-5247b0695a1914e16d1b6333aff6038c0bd578dc.tar.gz
libvirt-5247b0695a1914e16d1b6333aff6038c0bd578dc.tar.bz2
libvirt-5247b0695a1914e16d1b6333aff6038c0bd578dc.zip
Ensure sanlock socket is labelled with the VM process label
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
-rw-r--r--src/locking/domain_lock.c11
-rw-r--r--src/locking/domain_lock.h3
-rw-r--r--src/locking/lock_driver.h9
-rw-r--r--src/locking/lock_driver_nop.c4
-rw-r--r--src/locking/lock_driver_sanlock.c6
-rw-r--r--src/locking/lock_manager.c10
-rw-r--r--src/locking/lock_manager.h3
-rw-r--r--src/qemu/qemu_process.c12
8 files changed, 42 insertions, 16 deletions
diff --git a/src/locking/domain_lock.c b/src/locking/domain_lock.c
index 56b535f2c..de1937c9c 100644
--- a/src/locking/domain_lock.c
+++ b/src/locking/domain_lock.c
@@ -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;
diff --git a/src/locking/domain_lock.h b/src/locking/domain_lock.h
index 40fadd413..dd35c7c5b 100644
--- a/src/locking/domain_lock.h
+++ b/src/locking/domain_lock.h
@@ -28,7 +28,8 @@
int virDomainLockProcessStart(virLockManagerPluginPtr plugin,
virDomainObjPtr dom,
- bool paused);
+ bool paused,
+ int *fd);
int virDomainLockProcessPause(virLockManagerPluginPtr plugin,
virDomainObjPtr dom,
char **state);
diff --git a/src/locking/lock_driver.h b/src/locking/lock_driver.h
index 2e71113fc..c9fe3683a 100644
--- a/src/locking/lock_driver.h
+++ b/src/locking/lock_driver.h
@@ -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:
diff --git a/src/locking/lock_driver_nop.c b/src/locking/lock_driver_nop.c
index 36a9083c9..69a5b3407 100644
--- a/src/locking/lock_driver_nop.c
+++ b/src/locking/lock_driver_nop.c
@@ -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;
}
diff --git a/src/locking/lock_driver_sanlock.c b/src/locking/lock_driver_sanlock.c
index adead7671..86db5b84d 100644
--- a/src/locking/lock_driver_sanlock.c
+++ b/src/locking/lock_driver_sanlock.c
@@ -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:
diff --git a/src/locking/lock_manager.c b/src/locking/lock_manager.c
index e97c738d7..7cd565912 100644
--- a/src/locking/lock_manager.c
+++ b/src/locking/lock_manager.c
@@ -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);
}
diff --git a/src/locking/lock_manager.h b/src/locking/lock_manager.h
index 13ad3723d..af91cc6d2 100644
--- a/src/locking/lock_manager.h
+++ b/src/locking/lock_manager.h
@@ -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);
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 6f5f581a5..88a31a3e5 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -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: