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

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