Blob Blame History Raw
From f06f903d5cb3c14853a7213b6a70c078380b7a62 Mon Sep 17 00:00:00 2001
Message-Id: <f06f903d5cb3c14853a7213b6a70c078380b7a62@dist-git>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Fri, 24 Jan 2020 15:05:50 +0100
Subject: [PATCH] qemu_conf: Avoid dereferencing NULL in
 virQEMUDriverGetHost{NUMACaps, CPU}

When fixing [1] I've ran attached reproducer and had it spawn
1024 threads and query capabilities XML in each one of them. This
lead libvirtd to hit the RLIMIT_NOFILE limit which was kind of
expected. What wasn't expected was a subsequent segfault. It
happened because virCPUProbeHost failed and returned NULL. We've
taken the NULL and passed it to virCapabilitiesHostNUMARef()
which dereferenced it. Code inspection showed the same flas in
virQEMUDriverGetHostNUMACaps(), so I'm fixing both places.

1: https://bugzilla.redhat.com/show_bug.cgi?id=1791790

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit cc361a34c53210d682dbc5f2d506b4a23b71e399)

https://bugzilla.redhat.com/show_bug.cgi?id=1794691

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Message-Id: <5de22b27463cd2803b3910d7ef45a0e4bc08ad47.1579874719.git.mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
---
 src/qemu/qemu_conf.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 3d2f0e7bbb..e33ef4895e 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1201,32 +1201,42 @@ virQEMUDriverCreateXMLConf(virQEMUDriverPtr driver,
 virCapsHostNUMAPtr
 virQEMUDriverGetHostNUMACaps(virQEMUDriverPtr driver)
 {
+    virCapsHostNUMAPtr hostnuma;
+
     qemuDriverLock(driver);
 
     if (!driver->hostnuma)
         driver->hostnuma = virCapabilitiesHostNUMANewHost();
 
+    hostnuma = driver->hostnuma;
+
     qemuDriverUnlock(driver);
 
-    virCapabilitiesHostNUMARef(driver->hostnuma);
+    if (hostnuma)
+        virCapabilitiesHostNUMARef(hostnuma);
 
-    return driver->hostnuma;
+    return hostnuma;
 }
 
 
 virCPUDefPtr
 virQEMUDriverGetHostCPU(virQEMUDriverPtr driver)
 {
+    virCPUDefPtr hostcpu;
+
     qemuDriverLock(driver);
 
     if (!driver->hostcpu)
         driver->hostcpu = virCPUProbeHost(virArchFromHost());
 
+    hostcpu = driver->hostcpu;
+
     qemuDriverUnlock(driver);
 
-    virCPUDefRef(driver->hostcpu);
+    if (hostcpu)
+        virCPUDefRef(hostcpu);
 
-    return driver->hostcpu;
+    return hostcpu;
 }
 
 
-- 
2.25.0