DF-3311 / fix.diff
--- a/sys/net/wg/if_wg.c +++ b/sys/net/wg/if_wg.c @@ -2759,6 +2759,17 @@ } ifp->if_flags &= ~IFF_RUNNING; + /* + * Close the sockets BEFORE cancelling/purging anything below, so + * that no new wg_upcall() -> wg_input() can enqueue handshake + * packets and re-enqueue the tasks we are about to cancel, and + * which wg_clone_destroy() later frees along with the softc. + * (An airtight fix additionally needs a softc reference held + * across wg_input(); this closes the systematic re-enqueue + * window that races task cancel/purge with an open socket.) + */ + wg_socket_uninit(sc); + /* Cancel all tasks. */ while (taskqueue_cancel(sc->sc_handshake_taskqueue, &sc->sc_handshake_task, NULL) != 0) { @@ -2792,7 +2803,6 @@ ifp->if_link_state = LINK_STATE_DOWN; if_link_state_change(ifp); - wg_socket_uninit(sc); lockmgr(&sc->sc_lock, LK_RELEASE); } |