From b170e74a5fce3ef07ff69cc69b65c14b60f1f909 Mon Sep 17 00:00:00 2001 From: mvs Date: Fri, 12 Aug 2022 16:38:09 +0000 Subject: [PATCH] Fix race between pflow_output_process() and pflow_clone_destroy(). Unlink pflow(4) interface from `pflowif_list' before start destruction to prevent pflow_output_process() being rescheduled. Also wait until running pflow_output_process() task finished. Problem reported and fix tested by Hrvoje Popovski. ok bluhm@ --- sys/net/if_pflow.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sys/net/if_pflow.c b/sys/net/if_pflow.c index e627e69bc46..5bdaccbc643 100644 --- a/sys/net/if_pflow.c +++ b/sys/net/if_pflow.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_pflow.c,v 1.94 2022/06/06 14:45:41 claudio Exp $ */ +/* $OpenBSD: if_pflow.c,v 1.95 2022/08/12 16:38:09 mvs Exp $ */ /* * Copyright (c) 2011 Florian Obser @@ -274,6 +274,10 @@ pflow_clone_destroy(struct ifnet *ifp) error = 0; + NET_LOCK(); + SLIST_REMOVE(&pflowif_list, sc, pflow_softc, sc_next); + NET_UNLOCK(); + if (timeout_initialized(&sc->sc_tmo)) timeout_del(&sc->sc_tmo); if (timeout_initialized(&sc->sc_tmo6)) @@ -282,6 +286,7 @@ pflow_clone_destroy(struct ifnet *ifp) timeout_del(&sc->sc_tmo_tmpl); pflow_flush(sc); task_del(net_tq(ifp->if_index), &sc->sc_outputtask); + taskq_barrier(net_tq(ifp->if_index)); mq_purge(&sc->sc_outputqueue); m_freem(sc->send_nam); if (sc->so != NULL) { @@ -293,9 +298,6 @@ pflow_clone_destroy(struct ifnet *ifp) if (sc->sc_flowsrc != NULL) free(sc->sc_flowsrc, M_DEVBUF, sc->sc_flowsrc->sa_len); if_detach(ifp); - NET_LOCK(); - SLIST_REMOVE(&pflowif_list, sc, pflow_softc, sc_next); - NET_UNLOCK(); free(sc, M_DEVBUF, sizeof(*sc)); return (error); } -- 2.20.1