982648
From 4f042ede2b84b5f6bdf8a36e0768462816f2c9b1 Mon Sep 17 00:00:00 2001
982648
Message-Id: <4f042ede2b84b5f6bdf8a36e0768462816f2c9b1@dist-git>
982648
From: John Ferlan <jferlan@redhat.com>
982648
Date: Thu, 26 Jul 2018 09:39:32 -0400
982648
Subject: [PATCH] nwfilter: Resolve SEGV for NWFilter Snoop processing
982648
982648
https://bugzilla.redhat.com/show_bug.cgi?id=1599973
982648
982648
Commit id fca9afa08 changed the @req->ifname to use
982648
@req->binding->portdevname fillingin the @req->binding
982648
in a similar way that @req->ifname would have been
982648
filled in during virNWFilterDHCPSnoopReq processing.
982648
982648
However, in doing so it did not take into account some
982648
code paths where the @req->binding should be checked
982648
instead of @req->binding->portdevname. These checks
982648
led to SEGVs in some cases during libvirtd reload
982648
processing in virNWFilterSnoopRemAllReqIter (for
982648
stop during nwfilterStateCleanup processing) and
982648
virNWFilterSnoopReqLeaseDel (for start during
982648
nwfilterStateInitialize processing).
982648
982648
In particular, when reading the nwfilter.leases file
982648
a new @req is created, but the @req->binding is not
982648
filled in. That's left to virNWFilterDHCPSnoopReq
982648
processing which checks if the @req already exists
982648
in the @virNWFilterSnoopState.snoopReqs hash table
982648
after adding a virNWFilterSnoopState.ifnameToKey
982648
entry for the @req->binding->portdevname by a
982648
@ref->ikey value.
982648
982648
NB: virNWFilterSnoopIPLeaseInstallRule and
982648
    virNWFilterDHCPSnoopThread do not need the
982648
    req->binding check since they can only be called
982648
    after the filter->binding is created/assigned.
982648
982648
Signed-off-by: John Ferlan <jferlan@redhat.com>
982648
ACKed-by: Michal Privoznik <mprivozn@redhat.com>
982648
(cherry picked from commit 5229494b01acf97dbc6f3028e9718667e9e1426a)
982648
Reviewed-by: Erik Skultety <eskultet@redhat.com>
982648
---
982648
 src/nwfilter/nwfilter_dhcpsnoop.c | 7 ++++---
982648
 1 file changed, 4 insertions(+), 3 deletions(-)
982648
982648
diff --git a/src/nwfilter/nwfilter_dhcpsnoop.c b/src/nwfilter/nwfilter_dhcpsnoop.c
982648
index 533c45f080..2ae134ed19 100644
982648
--- a/src/nwfilter/nwfilter_dhcpsnoop.c
982648
+++ b/src/nwfilter/nwfilter_dhcpsnoop.c
982648
@@ -846,7 +846,7 @@ virNWFilterSnoopReqLeaseDel(virNWFilterSnoopReqPtr req,
982648
     int ret = 0;
982648
     virNWFilterSnoopIPLeasePtr ipl;
982648
     char *ipstr = NULL;
982648
-    int ipAddrLeft;
982648
+    int ipAddrLeft = 0;
982648
 
982648
     /* protect req->start, req->ifname and the lease */
982648
     virNWFilterSnoopReqLock(req);
982648
@@ -867,7 +867,8 @@ virNWFilterSnoopReqLeaseDel(virNWFilterSnoopReqPtr req,
982648
     if (update_leasefile)
982648
         virNWFilterSnoopLeaseFileSave(ipl);
982648
 
982648
-    ipAddrLeft = virNWFilterIPAddrMapDelIPAddr(req->binding->portdevname, ipstr);
982648
+    if (req->binding)
982648
+        ipAddrLeft = virNWFilterIPAddrMapDelIPAddr(req->binding->portdevname, ipstr);
982648
 
982648
     if (!req->threadkey || !instantiate)
982648
         goto skip_instantiate;
982648
@@ -2037,7 +2038,7 @@ virNWFilterSnoopRemAllReqIter(const void *payload,
982648
     /* protect req->binding->portdevname */
982648
     virNWFilterSnoopReqLock(req);
982648
 
982648
-    if (req->binding->portdevname) {
982648
+    if (req->binding && req->binding->portdevname) {
982648
         ignore_value(virHashRemoveEntry(virNWFilterSnoopState.ifnameToKey,
982648
                                         req->binding->portdevname));
982648
 
982648
-- 
982648
2.18.0
982648