This fixes a race condition when VIR_EVENT_HANDLE_HANGUP is triggered
during lxcDomainDestroyFlags: lxcMonitorEvent tries to acquire the
driver lock held by lxcDomainDestroyFlags and blocks. Meanwhile
lxcDomainDestroyFlags will free the "vm" structure and release the driver
lock. lxcMonitorEvent unblocks and operates on an invalid "vm" pointer.
By using virDomainFindbyID lxcMonitorEvent avoids using an invalid vm
pointer.
---
src/lxc/lxc_driver.c | 13 +++++++++----
1 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 3af8084..c55e164 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -1523,12 +1523,17 @@ static void lxcMonitorEvent(int watch,
void *data)
{
lxc_driver_t *driver = lxc_driver;
- virDomainObjPtr vm = data;
+ int id = (int)data;
+ virDomainObjPtr vm = NULL;
virDomainEventPtr event = NULL;
lxcDomainObjPrivatePtr priv;
lxcDriverLock(driver);
- virDomainObjLock(vm);
+ vm = virDomainFindByID(&driver->domains, id);
+ if (vm == NULL) {
+ lxcDriverUnlock(driver);
+ goto cleanup;
+ }
lxcDriverUnlock(driver);
priv = vm->privateData;
@@ -1950,7 +1955,7 @@ static int lxcVmStart(virConnectPtr conn,
priv->monitor,
VIR_EVENT_HANDLE_ERROR | VIR_EVENT_HANDLE_HANGUP,
lxcMonitorEvent,
- vm, NULL)) < 0) {
+ (void*)vm->def->id, NULL)) < 0) {
goto error;
}
@@ -2513,7 +2518,7 @@ lxcReconnectVM(void *payload, const void *name ATTRIBUTE_UNUSED,
void *opaque)
priv->monitor,
VIR_EVENT_HANDLE_ERROR | VIR_EVENT_HANDLE_HANGUP,
lxcMonitorEvent,
- vm, NULL)) < 0)
+ (void*)vm->def->id, NULL)) < 0)
goto error;
if (virSecurityManagerReserveLabel(driver->securityManager,
--
1.7.2.5