git: 5d45e09d50e6 - stable/13 - infiniband: Widen NET_EPOCH coverage
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 10 Apr 2023 04:16:49 UTC
The branch stable/13 has been updated by zlei:
URL: https://cgit.FreeBSD.org/src/commit/?id=5d45e09d50e648a75667c9b12b204eb62fa60ed2
commit 5d45e09d50e648a75667c9b12b204eb62fa60ed2
Author: Zhenlei Huang <zlei@FreeBSD.org>
AuthorDate: 2023-04-02 16:51:49 +0000
Commit: Zhenlei Huang <zlei@FreeBSD.org>
CommitDate: 2023-04-10 04:15:04 +0000
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
(cherry picked from commit 90820ef121b38479f2479c03c12c69f940f5fa33)
---
sys/net/if_infiniband.c | 4 ++--
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 4dfbd5272d15..9bf4756f2556 100644
--- a/sys/net/if_infiniband.c
+++ b/sys/net/if_infiniband.c
@@ -411,6 +411,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);
@@ -498,10 +499,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 3bbcb4f8e4cd..687c07971d60 100644
--- a/sys/net/if_lagg.c
+++ b/sys/net/if_lagg.c
@@ -2086,16 +2086,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);
}
@@ -2110,7 +2108,6 @@ lagg_input_infiniband(struct ifnet *ifp, struct mbuf *m)
}
}
- NET_EPOCH_EXIT(et);
return (m);
}