From 5247b0695a1914e16d1b6333aff6038c0bd578dc Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Fri, 24 Jun 2011 15:14:41 +0100 Subject: [PATCH] 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 --- src/locking/domain_lock.c | 11 ++++++----- src/locking/domain_lock.h | 3 ++- src/locking/lock_driver.h | 9 ++++++++- src/locking/lock_driver_nop.c | 4 ++-- src/locking/lock_driver_sanlock.c | 6 +++++- src/locking/lock_manager.c | 10 +++++++--- src/locking/lock_manager.h | 3 ++- src/qemu/qemu_process.c | 12 ++++++++++-- 8 files changed, 42 insertions(+), 16 deletions(-) diff --git a/src/locking/domain_lock.c b/src/locking/domain_lock.c index 56b535f2c5..de1937c9c9 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 40fadd413e..dd35c7c5bf 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 2e71113fc2..c9fe3683aa 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 36a9083c99..69a5b3407e 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 adead76712..86db5b84d4 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 e97c738d7c..7cd5659120 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 13ad3723d2..af91cc6d2d 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 6f5f581a5f..88a31a3e54 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: -- GitLab