ipsec: Drain async ipsec_offload work when destroying a vnet

The ipsec_offload code in some cases releases object references in an
asynchronous context where it needs to set the current VNET.  Make sure
that all such work completes before the VNET is actually destroyed,
otherwise a use-after-free is possible.

Reported by:	KASAN
Reviewed by:	kib
Fixes:		ef2a572bf6 ("ipsec_offload: kernel infrastructure")
Sponsored by:	Klara, Inc.
Differential Revision:	https://reviews.freebsd.org/D46483
This commit is contained in:
Mark Johnston 2024-08-30 00:44:45 +00:00
parent 356be1348d
commit e196b12f4d
2 changed files with 4 additions and 1 deletions

View file

@ -386,7 +386,7 @@ ipsec_accel_sa_newkey_impl(struct secasvar *sav)
TASK_INIT(&tq->install_task, 0, ipsec_accel_sa_newkey_act, tq);
tq->sav = sav;
tq->install_vnet = curthread->td_vnet; /* XXXKIB liveness */
tq->install_vnet = curthread->td_vnet;
taskqueue_enqueue(taskqueue_thread, &tq->install_task);
}

View file

@ -8713,6 +8713,9 @@ key_vnet_destroy(void *arg __unused)
}
SAHTREE_WUNLOCK();
/* Wait for async work referencing this VNET to finish. */
ipsec_accel_sync();
key_freesah_flushed(&sahdrainq);
hashdestroy(V_sphashtbl, M_IPSEC_SP, V_sphash_mask);
hashdestroy(V_savhashtbl, M_IPSEC_SA, V_savhash_mask);