aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhenlei Huang <zlei@FreeBSD.org>2023-04-02 16:51:49 +0000
committerZhenlei Huang <zlei@FreeBSD.org>2023-04-10 05:06:22 +0000
commit24069f0dc0730248bd5b09e50b12e37645d57c31 (patch)
treecb02a34571c878dffa5bb4aac9215323a7c089ff
parent11412682562925064591f0abaae63e2a9ff767e5 (diff)
downloadsrc-24069f0dc0730248bd5b09e50b12e37645d57c31.tar.gz
src-24069f0dc0730248bd5b09e50b12e37645d57c31.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 (cherry picked from commit 90820ef121b38479f2479c03c12c69f940f5fa33) (cherry picked from commit 5d45e09d50e648a75667c9b12b204eb62fa60ed2)
-rw-r--r--sys/net/if_infiniband.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/sys/net/if_infiniband.c b/sys/net/if_infiniband.c
index b644f91f2cda..3fe4fb0616e8 100644
--- a/sys/net/if_infiniband.c
+++ b/sys/net/if_infiniband.c
@@ -407,6 +407,7 @@ infiniband_input(struct ifnet *ifp, struct mbuf *m)
int isr;
CURVNET_SET_QUIET(ifp->if_vnet);
+ NET_EPOCH_ENTER_ET(et);
if ((ifp->if_flags & IFF_UP) == 0) {
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
@@ -494,10 +495,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(et);
netisr_dispatch(isr, m);
- NET_EPOCH_EXIT_ET(et);
done:
+ NET_EPOCH_EXIT_ET(et);
CURVNET_RESTORE();
}