diff options
author | Zhenlei Huang <zlei@FreeBSD.org> | 2023-04-02 16:51:49 +0000 |
---|---|---|
committer | Zhenlei Huang <zlei@FreeBSD.org> | 2023-04-02 16:51:49 +0000 |
commit | 90820ef121b38479f2479c03c12c69f940f5fa33 (patch) | |
tree | 4f5a7589d64e2ad1cb0868d7551c660624614dac | |
parent | 3091d980f581753f86df4155057b4ef23eb3ad27 (diff) | |
download | src-90820ef121b38479f2479c03c12c69f940f5fa33.tar.gz src-90820ef121b38479f2479c03c12c69f940f5fa33.zip |
infiniband: Widen NET_EPOCH coverage
From static code analysis, some device drivers (cxgbe, mlx4, mthca, and qlnx)
do not enter net epoch before lagg_input_infiniband(). If IPoIB interface is a
member of lagg(4) interface, and after returning from lagg_input_infiniband()
the receiving interface of mbuf is set to lagg(4) interface, then when
concurrently destroying the lagg(4) interface, there is a small window that the
interface gets destroyed and becomes invalid before infiniband_input() re-enter
net epoch, thus leading use-after-free.
Widen NET_EPOCH coverage to prevent use-after-free.
Thanks hselasky@ for testing with mlx5 devices.
Reviewed by: hselasky
Tested by: hselasky
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D39275
-rw-r--r-- | sys/net/if_infiniband.c | 4 | ||||
-rw-r--r-- | sys/net/if_lagg.c | 5 |
2 files changed, 3 insertions, 6 deletions
diff --git a/sys/net/if_infiniband.c b/sys/net/if_infiniband.c index 6ca90ba1d8c7..b3cdd15c76f7 100644 --- a/sys/net/if_infiniband.c +++ b/sys/net/if_infiniband.c @@ -417,6 +417,7 @@ infiniband_input(struct ifnet *ifp, struct mbuf *m) int isr; CURVNET_SET_QUIET(ifp->if_vnet); + NET_EPOCH_ENTER(et); if ((ifp->if_flags & IFF_UP) == 0) { if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); @@ -504,10 +505,9 @@ infiniband_input(struct ifnet *ifp, struct mbuf *m) mac_ifnet_create_mbuf(ifp, m); #endif /* Allow monitor mode to claim this frame, after stats are updated. */ - NET_EPOCH_ENTER(et); netisr_dispatch(isr, m); - NET_EPOCH_EXIT(et); done: + NET_EPOCH_EXIT(et); CURVNET_RESTORE(); } diff --git a/sys/net/if_lagg.c b/sys/net/if_lagg.c index cf78b55f4c34..b3475839a2c1 100644 --- a/sys/net/if_lagg.c +++ b/sys/net/if_lagg.c @@ -2192,16 +2192,14 @@ lagg_input_ethernet(struct ifnet *ifp, struct mbuf *m) static struct mbuf * lagg_input_infiniband(struct ifnet *ifp, struct mbuf *m) { - struct epoch_tracker et; struct lagg_port *lp = ifp->if_lagg; struct lagg_softc *sc = lp->lp_softc; struct ifnet *scifp = sc->sc_ifp; - NET_EPOCH_ENTER(et); + NET_EPOCH_ASSERT(); if ((scifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || lp->lp_detaching != 0 || sc->sc_proto == LAGG_PROTO_NONE) { - NET_EPOCH_EXIT(et); m_freem(m); return (NULL); } @@ -2214,7 +2212,6 @@ lagg_input_infiniband(struct ifnet *ifp, struct mbuf *m) m = NULL; } - NET_EPOCH_EXIT(et); return (m); } |