diff options
author | Zhenlei Huang <zlei@FreeBSD.org> | 2023-04-02 16:51:49 +0000 |
---|---|---|
committer | Zhenlei Huang <zlei@FreeBSD.org> | 2023-04-10 05:06:22 +0000 |
commit | 24069f0dc0730248bd5b09e50b12e37645d57c31 (patch) | |
tree | cb02a34571c878dffa5bb4aac9215323a7c089ff | |
parent | 11412682562925064591f0abaae63e2a9ff767e5 (diff) | |
download | src-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.c | 4 |
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(); } |