[PATCH v2] qemu: Fix crash in qemuProcessStop due to NULL eventThread
When a VM shuts down, the monitor EOF event is queued to the worker thread pool. If another thread enters qemuProcessStop() first and frees priv->eventThread via g_steal_pointer(), the second call from the EOF event worker thread hits a NULL dereference when calling virEventThreadStop(priv->eventThread). The existing 'if (priv->eventThread)' guard is insufficient because the VM object is unlocked between the check and the call to virEventThreadStop(), allowing a concurrent thread to clear the pointer in the meantime. Fix this by taking a GObject reference to eventThread before unlocking the VM. This ensures the pointer remains valid for virEventThreadStop() even if another thread clears priv->eventThread concurrently. Crash backtrace: #0 virEventThreadStop (evt=0x0) #1 qemuProcessStop (reason=VIR_DOMAIN_SHUTOFF_SHUTDOWN, asyncJob=VIR_ASYNC_JOB_NONE) #2 processMonitorEOFEvent (driver=..., vm=...) #3 qemuProcessEventHandler (data=..., opaque=...) #4 virThreadPoolWorker (opaque=...) Signed-off-by: Pritam Srichandan Sahoo <PritamSrichandan.Sahoo@windriver.com> --- v2: Resend as an inline plain-text patch. The v1 posting was delivered as an email attachment which is harder to review; no code changes from v1. src/qemu/qemu_process.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 0d9b8bcb93..642e18eeb1 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -8850,13 +8850,15 @@ void qemuProcessStop(virQEMUDriver *driver, * the global domain object list code depends on it (and it can't actually * check 'priv->beingDestroyed as that's private). */ if (priv->eventThread) { + virEventThread *eventThread = g_object_ref(priv->eventThread); /* Explicitly set priv->beingDestroyed. While it's done in * qemuProcessBeginStopJob(), qemuProcessStop() is called from places * where stop job is not acquired. */ priv->beingDestroyed = true; virObjectUnlock(vm); - virEventThreadStop(priv->eventThread); + virEventThreadStop(eventThread); virObjectLock(vm); + g_object_unref(eventThread); } if (priv->agent) { -- 2.53.0
participants (1)
-
Pritam Srichandan Sahoo