From b0abd50cf05f84e62763a8088981b0538d910d46 Mon Sep 17 00:00:00 2001 From: kp Date: Tue, 8 Sep 2020 14:54:10 +0000 Subject: [PATCH] net: mitigate vnet / epair cleanup races There's a race where dying vnets move their interfaces back to their original vnet, and if_epair cleanup (where deleting one interface also deletes the other end of the epair). This is commonly triggered by the pf tests, but also by cleanup of vnet jails. As we've not yet been able to fix the root cause of the issue work around the panic by not dereferencing a NULL softc in epair_qflush() and by not re-attaching DYING interfaces. This isn't a full fix, but makes a very common panic far less likely. PR: 244703, 238870 Reviewed by: lutz_donnerhacke.de MFC after: 4 days Differential Revision: https://reviews.freebsd.org/D26324 --- sys/net/if.c | 5 +++++ sys/net/if_epair.c | 10 ++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/sys/net/if.c b/sys/net/if.c index 2fd17e00c31..884d0b60c73 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1298,6 +1298,11 @@ if_vmove(struct ifnet *ifp, struct vnet *new_vnet) ifindex_free_locked(ifp->if_index); IFNET_WUNLOCK(); + + /* Don't re-attach DYING interfaces. */ + if (ifp->if_flags & IFF_DYING) + return (0); + /* * Perform interface-specific reassignment tasks, if provided by * the driver. diff --git a/sys/net/if_epair.c b/sys/net/if_epair.c index 7f62cdb427f..2c29a4fdf63 100644 --- a/sys/net/if_epair.c +++ b/sys/net/if_epair.c @@ -611,8 +611,14 @@ epair_qflush(struct ifnet *ifp) struct epair_softc *sc; sc = ifp->if_softc; - KASSERT(sc != NULL, ("%s: ifp=%p, epair_softc gone? sc=%p\n", - __func__, ifp, sc)); + + /* + * See epair_clone_destroy(), we can end up getting called twice. + * Don't do anything on the second call. + */ + if (sc == NULL) + return; + /* * Remove this ifp from all backpointer lists. The interface will not * usable for flushing anyway nor should it have anything to flush -- 2.45.0