Blame SOURCES/libvirt-virnwfilterbindingobj-Introduce-and-use-virNWFilterBindingObjStealDef.patch

9b85a9
From 48289dddc0f4398036071c132f96644e3c3e03c4 Mon Sep 17 00:00:00 2001
9b85a9
Message-Id: <48289dddc0f4398036071c132f96644e3c3e03c4@dist-git>
9b85a9
From: Michal Privoznik <mprivozn@redhat.com>
9b85a9
Date: Tue, 23 Apr 2019 10:06:17 +0200
9b85a9
Subject: [PATCH] virnwfilterbindingobj: Introduce and use
9b85a9
 virNWFilterBindingObjStealDef
9b85a9
MIME-Version: 1.0
9b85a9
Content-Type: text/plain; charset=UTF-8
9b85a9
Content-Transfer-Encoding: 8bit
9b85a9
9b85a9
RHEL-7.7: https://bugzilla.redhat.com/show_bug.cgi?id=1686927
9b85a9
RHEL-7.6.z: https://bugzilla.redhat.com/show_bug.cgi?id=1702173
9b85a9
9b85a9
When trying to create a nwfilter binding via
9b85a9
nwfilterBindingCreateXML() we may encounter a crash. The sequence
9b85a9
of functions called is as follows:
9b85a9
9b85a9
1) nwfilterBindingCreateXML() parses the XML and calls
9b85a9
virNWFilterBindingObjListAdd() which calls
9b85a9
virNWFilterBindingObjListAddLocked()
9b85a9
9b85a9
2) Here, @binding is not found because binding->remove is set.
9b85a9
9b85a9
3) Therefore, controls continue with creating new @binding,
9b85a9
setting its def to the one from 1) and adding it to the hash
9b85a9
table.
9b85a9
9b85a9
4) This fails, because the binding is still in the hash table
9b85a9
(duplicate key is detected).
9b85a9
9b85a9
5) The control jumps to 'error' label where
9b85a9
virNWFilterBindingObjEndAPI() is called which frees the binding
9b85a9
definition passed.
9b85a9
9b85a9
6) Error is propagated to the caller, which calls
9b85a9
virNWFilterBindingDefFree() over the definition again.
9b85a9
9b85a9
The solution is to unset binding->def in case of failure so it's
9b85a9
not freed in step 5).
9b85a9
9b85a9
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
9b85a9
Reviewed-by: Ján Tomko <jtomko@redhat.com>
9b85a9
(cherry picked from commit 8c08a99745ddac9f4055c008e82e68a27ed5093d)
9b85a9
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
9b85a9
Message-Id: <a5c2feed107e958bb6a84f7e993cc9feac58c4a2.1556006751.git.mprivozn@redhat.com>
9b85a9
Reviewed-by: Ján Tomko <jtomko@redhat.com>
9b85a9
---
9b85a9
 src/conf/virnwfilterbindingobj.c     | 10 ++++++++++
9b85a9
 src/conf/virnwfilterbindingobj.h     |  3 +++
9b85a9
 src/conf/virnwfilterbindingobjlist.c |  4 ++++
9b85a9
 src/libvirt_private.syms             |  1 +
9b85a9
 4 files changed, 18 insertions(+)
9b85a9
9b85a9
diff --git a/src/conf/virnwfilterbindingobj.c b/src/conf/virnwfilterbindingobj.c
9b85a9
index d145fe3223..291ba9a5f8 100644
9b85a9
--- a/src/conf/virnwfilterbindingobj.c
9b85a9
+++ b/src/conf/virnwfilterbindingobj.c
9b85a9
@@ -88,6 +88,16 @@ virNWFilterBindingObjSetDef(virNWFilterBindingObjPtr obj,
9b85a9
 }
9b85a9
 
9b85a9
 
9b85a9
+virNWFilterBindingDefPtr
9b85a9
+virNWFilterBindingObjStealDef(virNWFilterBindingObjPtr obj)
9b85a9
+{
9b85a9
+    virNWFilterBindingDefPtr def;
9b85a9
+
9b85a9
+    VIR_STEAL_PTR(def, obj->def);
9b85a9
+    return def;
9b85a9
+}
9b85a9
+
9b85a9
+
9b85a9
 bool
9b85a9
 virNWFilterBindingObjGetRemoving(virNWFilterBindingObjPtr obj)
9b85a9
 {
9b85a9
diff --git a/src/conf/virnwfilterbindingobj.h b/src/conf/virnwfilterbindingobj.h
9b85a9
index 21ae85b064..e8f94aa1ef 100644
9b85a9
--- a/src/conf/virnwfilterbindingobj.h
9b85a9
+++ b/src/conf/virnwfilterbindingobj.h
9b85a9
@@ -38,6 +38,9 @@ void
9b85a9
 virNWFilterBindingObjSetDef(virNWFilterBindingObjPtr obj,
9b85a9
                             virNWFilterBindingDefPtr def);
9b85a9
 
9b85a9
+virNWFilterBindingDefPtr
9b85a9
+virNWFilterBindingObjStealDef(virNWFilterBindingObjPtr obj);
9b85a9
+
9b85a9
 bool
9b85a9
 virNWFilterBindingObjGetRemoving(virNWFilterBindingObjPtr obj);
9b85a9
 
9b85a9
diff --git a/src/conf/virnwfilterbindingobjlist.c b/src/conf/virnwfilterbindingobjlist.c
9b85a9
index 7ce59f7c6e..d0301e7e28 100644
9b85a9
--- a/src/conf/virnwfilterbindingobjlist.c
9b85a9
+++ b/src/conf/virnwfilterbindingobjlist.c
9b85a9
@@ -169,6 +169,7 @@ virNWFilterBindingObjListAddLocked(virNWFilterBindingObjListPtr bindings,
9b85a9
                                    virNWFilterBindingDefPtr def)
9b85a9
 {
9b85a9
     virNWFilterBindingObjPtr binding;
9b85a9
+    bool stealDef = false;
9b85a9
 
9b85a9
     /* See if a binding with matching portdev already exists */
9b85a9
     if ((binding = virNWFilterBindingObjListFindByPortDevLocked(
9b85a9
@@ -183,6 +184,7 @@ virNWFilterBindingObjListAddLocked(virNWFilterBindingObjListPtr bindings,
9b85a9
         goto error;
9b85a9
 
9b85a9
     virNWFilterBindingObjSetDef(binding, def);
9b85a9
+    stealDef = true;
9b85a9
 
9b85a9
     if (virNWFilterBindingObjListAddObjLocked(bindings, binding) < 0)
9b85a9
         goto error;
9b85a9
@@ -190,6 +192,8 @@ virNWFilterBindingObjListAddLocked(virNWFilterBindingObjListPtr bindings,
9b85a9
     return binding;
9b85a9
 
9b85a9
  error:
9b85a9
+    if (stealDef)
9b85a9
+        virNWFilterBindingObjStealDef(binding);
9b85a9
     virNWFilterBindingObjEndAPI(&binding);
9b85a9
     return NULL;
9b85a9
 }
9b85a9
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
9b85a9
index 636891eabd..3325b90535 100644
9b85a9
--- a/src/libvirt_private.syms
9b85a9
+++ b/src/libvirt_private.syms
9b85a9
@@ -1065,6 +1065,7 @@ virNWFilterBindingObjParseFile;
9b85a9
 virNWFilterBindingObjSave;
9b85a9
 virNWFilterBindingObjSetDef;
9b85a9
 virNWFilterBindingObjSetRemoving;
9b85a9
+virNWFilterBindingObjStealDef;
9b85a9
 
9b85a9
 
9b85a9
 # conf/virnwfilterbindingobjlist.h
9b85a9
-- 
9b85a9
2.21.0
9b85a9