diff options
author | hrs <hrs@FreeBSD.org> | 2015-02-14 18:15:14 +0000 |
---|---|---|
committer | hrs <hrs@FreeBSD.org> | 2015-02-14 18:15:14 +0000 |
commit | aae7e542bc5f5d7e9d45cff295345b09440356f1 (patch) | |
tree | 378cb16dc2ca1dccb6cdef29a9c447b74f403f10 /sys/net/if_bridge.c | |
parent | 9b83a1eb03a39e0c25ec6c20050e639b2b443898 (diff) | |
download | FreeBSD-src-aae7e542bc5f5d7e9d45cff295345b09440356f1.zip FreeBSD-src-aae7e542bc5f5d7e9d45cff295345b09440356f1.tar.gz |
Fix a panic when tearing down a vnet on a VIMAGE-enabled kernel.
There was a race that bridge_ifdetach() could be called via
ifnet_departure event handler after vnet_bridge_uninit().
PR: 195859
Reported by: Danilo Egea Gondolfo
Diffstat (limited to 'sys/net/if_bridge.c')
-rw-r--r-- | sys/net/if_bridge.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index 019bbf5..753854d 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -228,7 +228,7 @@ struct bridge_softc { static VNET_DEFINE(struct mtx, bridge_list_mtx); #define V_bridge_list_mtx VNET(bridge_list_mtx) -eventhandler_tag bridge_detach_cookie = NULL; +static eventhandler_tag bridge_detach_cookie; int bridge_rtable_prune_period = BRIDGE_RTABLE_PRUNE_PERIOD; @@ -538,6 +538,7 @@ vnet_bridge_uninit(const void *unused __unused) { if_clone_detach(V_bridge_cloner); + V_bridge_cloner = NULL; BRIDGE_LIST_LOCK_DESTROY(); } VNET_SYSUNINIT(vnet_bridge_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, @@ -1797,7 +1798,13 @@ bridge_ifdetach(void *arg __unused, struct ifnet *ifp) if (ifp->if_flags & IFF_RENAMING) return; - + if (V_bridge_cloner == NULL) { + /* + * This detach handler can be called after + * vnet_bridge_uninit(). Just return in that case. + */ + return; + } /* Check if the interface is a bridge member */ if (sc != NULL) { BRIDGE_LOCK(sc); |