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