pppx_if_start() checks `IFF_RUNNING' bit to be sure `pxi' is consistent
but this bit is not cleared on `pxi' destroy. pppx_if_output() checks
`IFF_UP' bit for the same reason but this bit is always set and this
check is useless. pppac_output() checks `IFF_RUNNING' bit but
pppac_start() doesn't.
Diff below adds `IFF_RUNNING' clearing to pppx_if_destroy() before `pxi'
destruction to be sure this `pxi' can't be accessed from `ifnet' in
potencial context switch caused by if_detach().
In pppx_if_output() `IFF_RUNNING' checked instead of `IFF_UP' for
consistency with other code.
Also `IFF_RUNNING' checked in pppac_start().
Index: sys/net/if_pppx.c
===================================================================
RCS file: /cvs/src/sys/net/if_pppx.c,v
retrieving revision 1.89
diff -u -p -r1.89 if_pppx.c
--- sys/net/if_pppx.c 22 Jun 2020 10:01:03 -0000 1.89
+++ sys/net/if_pppx.c 22 Jun 2020 11:59:28 -0000
@@ -854,9 +854,10 @@ pppx_if_destroy(struct pppx_dev *pxd, st
struct pipex_session *session;
NET_ASSERT_LOCKED();
- pxi->pxi_ready = 0;
session = pxi->pxi_session;
ifp = &pxi->pxi_if;
+ pxi->pxi_ready = 0;
+ CLR(ifp->if_flags, IFF_RUNNING);
pipex_unlink_session(session);
@@ -910,7 +911,7 @@ pppx_if_output(struct ifnet *ifp, struct
NET_ASSERT_LOCKED();
- if (!ISSET(ifp->if_flags, IFF_UP)) {
+ if (!ISSET(ifp->if_flags, IFF_RUNNING)) {
m_freem(m);
error = ENETDOWN;
goto out;
@@ -1465,6 +1466,9 @@ pppac_start(struct ifnet *ifp)
{
struct pppac_softc *sc = ifp->if_softc;
struct mbuf *m;
+
+ if (!ISSET(ifp->if_flags, IFF_RUNNING))
+ return;
while ((m = ifq_dequeue(&ifp->if_snd)) != NULL) {
#if NBPFILTER > 0