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

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