From 5a72397ee12c82b7848cd736866538fa34c4a853 Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Fri, 3 Jun 2016 10:09:17 +0200 Subject: [PATCH] virPerfEventIsEnabled: Don't crash on shut off domains So imagine the following. You connect read only to a daemon and try to fetch stats for a shut off domain, e.g.: virsh -r domstats $dom but all of a sudden, virsh instead of printing the stats throws the following error at you: error: Disconnected from qemu:///system due to I/O error error: End of file while reading data: Input/output error The daemon crashed. This is its backtrace: #0 0x00007fa43e3751a8 in virPerfEventIsEnabled (perf=0x0, type=VIR_PERF_EVENT_MBMT) at util/virperf.c:241 #1 0x00007fa424a9f042 in qemuDomainGetStatsPerf (driver=0x7fa3f4022a30, dom=0x7fa3f40e24c0, record=0x7fa41c000e20, maxparams=0x7fa4360b38d0, privflags=1) at qemu/qemu_driver.c:19110 #2 0x00007fa424a9f2e7 in qemuDomainGetStats (conn=0x7fa41c001b20, dom=0x7fa3f40e24c0, stats=127, record=0x7fa4360b3970, flags=1) at qemu/qemu_driver.c:19213 #3 0x00007fa424a9f672 in qemuConnectGetAllDomainStats (conn=0x7fa41c001b20, doms=0x7fa41c0017f0, ndoms=1, stats=127, retStats=0x7fa4360b3a50, flags=0) at qemu/qemu_driver.c:19303 #4 0x00007fa43e4e15f6 in virDomainListGetStats (doms=0x7fa41c0017f0, stats=0, retStats=0x7fa4360b3a50, flags=0) at libvirt-domain.c:11615 Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 0x7f28d1a38700 (LWP 16154)] 0x00007f28da4fa1a8 in virPerfEventIsEnabled (perf=0x0, type=VIR_PERF_EVENT_MBMT) at util/virperf.c:241 241 return event->enabled; Problem is, shut off domains don't have priv->perf allocated. Therefore if in frame #1 qemuDomainGetStatsPerf() tries to check if perf events are enabled, NULL is passed to virPerfEventIsEnabled() which due to some incredible implementation dereference it. Fix this by checking whether passed object is not NULL. Signed-off-by: Michal Privoznik --- src/util/virperf.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/util/virperf.c b/src/util/virperf.c index a0997f94b1..4661ba3fb1 100644 --- a/src/util/virperf.c +++ b/src/util/virperf.c @@ -99,6 +99,9 @@ static virPerfEventPtr virPerfGetEvent(virPerfPtr perf, virPerfEventType type) { + if (!perf) + return NULL; + if (type >= VIR_PERF_EVENT_LAST) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Event '%d' is not supported"),