SHA256
1
0
forked from pool/libvirt
libvirt/33c6eb96-fix-libvirtd-reload-deadlock.patch
James Fehlig a026aabb02 Accepting request 586966 from home:jfehlig:branches:Virtualization
- qemu: avoid denial of service reading from QEMU guest agent
  CVE-2018-1064
  fbf31e1a-CVE-2018-1064.patch
  bsc#1083625

- virtlockd: fix loosing lock on re-exec
  464889ff-rpc-aquire-ref-dispatch.patch,
  c6f1d519-rpc-simplify-dispatch.patch,
  06e7ebb6-rpc-invoke-dispatch-unlocked.patch,
  86cae503-rpc-fix-pre-exec.patch,
  eefabb38-rpc-virtlockd-virtlogd-single-thread.patch
  bsc#1076861

- libvirtd: fix potential deadlock when reloading
  33c6eb96-fix-libvirtd-reload-deadlock.patch
  bsc#1079150

OBS-URL: https://build.opensuse.org/request/show/586966
OBS-URL: https://build.opensuse.org/package/show/Virtualization/libvirt?expand=0&rev=676
2018-03-14 14:29:10 +00:00

116 lines
4.7 KiB
Diff

commit 33c6eb9689eb51dfe31dd05b24b3b6b1c948c267
Author: Jim Fehlig <jfehlig@suse.com>
Date: Thu Mar 8 15:04:48 2018 -0700
libvirtd: fix potential deadlock when reloading
It is possible to deadlock libvirtd when concurrently starting a domain
and restarting the daemon. Threads involved in the deadlock are
Thread 4 (Thread 0x7fc13b53e700 (LWP 64084)):
/lib64/libpthread.so.0
at util/virthread.c:154
at qemu/qemu_monitor.c:1083
cmd=0x7fc110017700, scm_fd=-1, reply=0x7fc13b53d318) at
qemu/qemu_monitor_json.c:305
cmd=0x7fc110017700,
reply=0x7fc13b53d318) at qemu/qemu_monitor_json.c:335
at qemu/qemu_monitor_json.c:1298
at qemu/qemu_monitor.c:1697
vm=0x7fc110003d00, asyncJob=QEMU_ASYNC_JOB_START) at qemu/qemu_process.c:1763
vm=0x7fc110003d00,
asyncJob=6, logCtxt=0x7fc1100089c0) at qemu/qemu_process.c:1835
vm=0x7fc110003d00, asyncJob=6, logCtxt=0x7fc1100089c0) at
qemu/qemu_process.c:2180
driver=0x7fc12004e1e0,
vm=0x7fc110003d00, asyncJob=QEMU_ASYNC_JOB_START, incoming=0x0, snapshot=0x0,
vmop=VIR_NETDEV_VPORT_PROFILE_OP_CREATE, flags=17) at qemu/qemu_process.c:6111
driver=0x7fc12004e1e0,
vm=0x7fc110003d00, updatedCPU=0x0, asyncJob=QEMU_ASYNC_JOB_START,
migrateFrom=0x0,
migrateFd=-1, migratePath=0x0, snapshot=0x0,
vmop=VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
flags=17) at qemu/qemu_process.c:6334
xml=0x7fc110000ed0 "<!--\nWARNING: THIS IS AN AUTO-GENERATED FILE.
CHANGES TO IT ARE LIKELY TO BE\nOVERWRITTEN AND LOST. Changes to this xml
configuration should be made using:\n virsh edit testvv\nor other
applicati"..., flags=0) at qemu/qemu_driver.c:1776
...
Thread 1 (Thread 0x7fc143c66880 (LWP 64081)):
/lib64/libpthread.so.0
at util/virthread.c:122
conf/nwfilter_conf.c:159
sig=0x7ffe0a831e30,
opaque=0x0) at remote/remote_daemon.c:724
opaque=0x558c5328b230) at rpc/virnetdaemon.c:654
at util/vireventpoll.c:508
rpc/virnetdaemon.c:858
remote/remote_daemon.c:1496
(gdb) thr 1
[Switching to thread 1 (Thread 0x7fc143c66880 (LWP 64081))]
/lib64/libpthread.so.0
(gdb) f 1
at util/virthread.c:122
122 pthread_rwlock_wrlock(&m->lock);
(gdb) p updateLock
$1 = {lock = {__data = {__lock = 0, __nr_readers = 1, __readers_wakeup = 0,
__writer_wakeup = 0, __nr_readers_queued = 0, __nr_writers_queued = 1,
__writer = 0,
__shared = 0, __rwelision = 0 '\000', __pad1 = "\000\000\000\000\000\000",
__pad2 = 0, __flags = 0},
__size = "\000\000\000\000\001", '\000' <repeats 15 times>, "\001",
'\000' <repeats 34 times>, __align = 4294967296}}
Reloading of the nwfilter driver is stuck waiting for a write lock, which
already has a reader (from qemuDomainCreateXML) in the critical section.
Since the reload occurs in the context of the main event loop thread,
libvirtd becomes deadlocked. The deadlock can be avoided by offloading
the reload work to a thread.
Signed-off-by: Jim Fehlig <jfehlig@suse.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Index: libvirt-4.1.0/src/remote/remote_daemon.c
===================================================================
--- libvirt-4.1.0.orig/src/remote/remote_daemon.c
+++ libvirt-4.1.0/src/remote/remote_daemon.c
@@ -709,20 +709,32 @@ static void daemonShutdownHandler(virNet
virNetDaemonQuit(dmn);
}
+static void daemonReloadHandlerThread(void *opague ATTRIBUTE_UNUSED)
+{
+ VIR_INFO("Reloading configuration on SIGHUP");
+ virHookCall(VIR_HOOK_DRIVER_DAEMON, "-",
+ VIR_HOOK_DAEMON_OP_RELOAD, SIGHUP, "SIGHUP", NULL, NULL);
+ if (virStateReload() < 0)
+ VIR_WARN("Error while reloading drivers");
+}
+
static void daemonReloadHandler(virNetDaemonPtr dmn ATTRIBUTE_UNUSED,
siginfo_t *sig ATTRIBUTE_UNUSED,
void *opaque ATTRIBUTE_UNUSED)
{
+ virThread thr;
+
if (!driversInitialized) {
VIR_WARN("Drivers are not initialized, reload ignored");
return;
}
- VIR_INFO("Reloading configuration on SIGHUP");
- virHookCall(VIR_HOOK_DRIVER_DAEMON, "-",
- VIR_HOOK_DAEMON_OP_RELOAD, SIGHUP, "SIGHUP", NULL, NULL);
- if (virStateReload() < 0)
- VIR_WARN("Error while reloading drivers");
+ if (virThreadCreate(&thr, false, daemonReloadHandlerThread, NULL) < 0) {
+ /*
+ * Not much we can do on error here except log it.
+ */
+ VIR_ERROR(_("Failed to create thread to handle daemon restart"));
+ }
}
static int daemonSetupSignals(virNetDaemonPtr dmn)