From: Pavel Hrdina <[email protected]>

Currently virDomainNetDef and virDomainActualNetDef use
virDomainHostdevDef directly as structure and the code doesn't call
virDomainHostdevDefNew() that would initialize private data.

This is hackish quick fix to solve a crash that happens in two
scenarios:

1. attaching any interface with hostdev backend

0x0000fffbfc0e2a90 in qemuDomainAttachHostPCIDevice (driver=0xfffbb4006750, 
vm=0xfffbf001f790, hostdev=0xfffbf400b150) at ../src/qemu/qemu_hotplug.c:1652
1652 if ((ret = qemuFDPassDirectTransferMonitor(hostdevPriv->vfioDeviceFd, 
priv->mon)) < 0)

2. starting VM with interface with hostdev backend using iommufd

0x00007f6638d5b9ca in qemuProcessOpenVfioDeviceFd 
(hostdev=hostdev@entry=0x7f6634425ee0) at ../src/qemu/qemu_process.c:7719
7719        hostdevPriv->vfioDeviceFd = qemuFDPassDirectNew(name, 
&vfioDeviceFd);

Proper fix for this issue is to refactor network code to use pointer and to
use virDomainHostdevDefNew().

Signed-off-by: Pavel Hrdina <[email protected]>
---
 src/conf/domain_conf.c | 23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 3528b90742..8090becdcf 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3517,6 +3517,20 @@ void virDomainVideoDefFree(virDomainVideoDef *def)
 }
 
 
+static int
+virDomainHostdevDefPrivateDataNew(virDomainHostdevDef *def,
+                                  virDomainXMLOption *xmlopt)
+{
+    if (!xmlopt || !xmlopt->privateData.hostdevNew)
+        return 0;
+
+    if (!(def->privateData = xmlopt->privateData.hostdevNew()))
+        return -1;
+
+    return 0;
+}
+
+
 virDomainHostdevDef *
 virDomainHostdevDefNew(virDomainXMLOption *xmlopt)
 {
@@ -3526,8 +3540,7 @@ virDomainHostdevDefNew(virDomainXMLOption *xmlopt)
 
     def->info = g_new0(virDomainDeviceInfo, 1);
 
-    if (xmlopt && xmlopt->privateData.hostdevNew &&
-        !(def->privateData = xmlopt->privateData.hostdevNew())) {
+    if (virDomainHostdevDefPrivateDataNew(def, xmlopt) < 0) {
         VIR_FREE(def->info);
         VIR_FREE(def);
         return NULL;
@@ -9739,6 +9752,9 @@ virDomainActualNetDefParseXML(xmlNodePtr node,
         virDomainHostdevDef *hostdev = &actual->data.hostdev.def;
         int type;
 
+        if (virDomainHostdevDefPrivateDataNew(hostdev, xmlopt) < 0)
+            goto error;
+
         hostdev->parentnet = parent;
         hostdev->info = &parent->info;
         /* The helper function expects type to already be found and
@@ -10432,6 +10448,9 @@ virDomainNetDefParseXML(virDomainXMLOption *xmlopt,
         g_autofree char *addrtype = 
virXPathString("string(./source/address/@type)", ctxt);
         int type;
 
+        if (virDomainHostdevDefPrivateDataNew(&def->data.hostdev.def, xmlopt) 
< 0)
+            return NULL;
+
         def->data.hostdev.def.parentnet = def;
         def->data.hostdev.def.info = &def->info;
         def->data.hostdev.def.mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
-- 
2.53.0

Reply via email to