diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 24f704736d..17e5eff511 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1047,6 +1047,8 @@ virSecurityManagerGetProcessLabel; virSecurityManagerNew; virSecurityManagerNewStack; virSecurityManagerNewDAC; +virSecurityManagerPostFork; +virSecurityManagerPreFork; virSecurityManagerReleaseLabel; virSecurityManagerReserveLabel; virSecurityManagerRestoreImageLabel; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index cfadc2c3e8..01c68806dd 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -2579,6 +2579,11 @@ static int qemuProcessHook(void *data) struct qemuProcessHookData *h = data; int ret = -1; int fd; + /* This method cannot use any mutexes, which are not + * protected across fork() + */ + + virSecurityManagerPostFork(h->driver->securityManager); /* Some later calls want pid present */ h->vm->pid = getpid(); @@ -3640,7 +3645,9 @@ int qemuProcessStart(virConnectPtr conn, virCommandDaemonize(cmd); virCommandRequireHandshake(cmd); + virSecurityManagerPreFork(driver->securityManager); ret = virCommandRun(cmd, NULL); + virSecurityManagerPostFork(driver->securityManager); /* wait for qemu process to show up */ if (ret == 0) { diff --git a/src/security/security_manager.c b/src/security/security_manager.c index d446607fcd..fc7acff4d2 100644 --- a/src/security/security_manager.c +++ b/src/security/security_manager.c @@ -161,6 +161,26 @@ virSecurityManagerPtr virSecurityManagerNew(const char *name, requireConfined); } + +/* + * Must be called before fork()'ing to ensure mutex state + * is sane for the child to use + */ +void virSecurityManagerPreFork(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED) +{ + /* XXX Grab our own mutex here instead of relying on caller's mutex */ +} + + +/* + * Must be called after fork()'ing in both parent and child + * to ensure mutex state is sane for the child to use + */ +void virSecurityManagerPostFork(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED) +{ + /* XXX Release our own mutex here instead of relying on caller's mutex */ +} + void *virSecurityManagerGetPrivateData(virSecurityManagerPtr mgr) { /* This accesses the memory just beyond mgr, which was allocated diff --git a/src/security/security_manager.h b/src/security/security_manager.h index 1fdaf8e964..d1a59974ea 100644 --- a/src/security/security_manager.h +++ b/src/security/security_manager.h @@ -46,6 +46,9 @@ virSecurityManagerPtr virSecurityManagerNewDAC(const char *virtDriver, bool requireConfined, bool dynamicOwnership); +void virSecurityManagerPreFork(virSecurityManagerPtr mgr); +void virSecurityManagerPostFork(virSecurityManagerPtr mgr); + void *virSecurityManagerGetPrivateData(virSecurityManagerPtr mgr); void virSecurityManagerFree(virSecurityManagerPtr mgr);