Add the check that current VNET is ready and access to srchash is
allowed. ipsec_srcaddr() callback can be called during VNET teardown, since ingress address checking subsystem isn't VNET specific. And thus callback can make access to already freed memory. To prevent this, use V_ipsec_idhtbl pointer as indicator of VNET readiness. And make epoch_wait() after resetting it to NULL in vnet_ipsec_uninit() to be sure that ipsec_srcaddr() is finished its work. Reported by: kp MFC after: 20 days
This commit is contained in:
parent
5acedb55c0
commit
221022e190
@ -273,6 +273,13 @@ vnet_ipsec_uninit(const void *unused __unused)
|
||||
|
||||
if_clone_detach(V_ipsec_cloner);
|
||||
free(V_ipsec_idhtbl, M_IPSEC);
|
||||
/*
|
||||
* Use V_ipsec_idhtbl pointer as indicator that VNET is going to be
|
||||
* destroyed, it is used by ipsec_srcaddr() callback.
|
||||
*/
|
||||
V_ipsec_idhtbl = NULL;
|
||||
IPSEC_WAIT();
|
||||
|
||||
#ifdef INET
|
||||
if (IS_DEFAULT_VNET(curvnet))
|
||||
ip_encap_unregister_srcaddr(ipsec4_srctab);
|
||||
@ -785,6 +792,10 @@ ipsec_srcaddr(void *arg __unused, const struct sockaddr *sa,
|
||||
struct ipsec_softc *sc;
|
||||
struct secasindex *saidx;
|
||||
|
||||
/* Check that VNET is ready */
|
||||
if (V_ipsec_idhtbl == NULL)
|
||||
return;
|
||||
|
||||
MPASS(in_epoch(net_epoch_preempt));
|
||||
CK_LIST_FOREACH(sc, ipsec_srchash(sa), srchash) {
|
||||
if (sc->family == 0)
|
||||
|
Loading…
x
Reference in New Issue
Block a user