⬢ DragonFlyBSD Kernel Audit
DF-3311 / fix.diff
← back to finding ↓ download raw
--- 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);
 }