The branch main has been updated by zlei:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=90820ef121b38479f2479c03c12c69f940f5fa33

commit 90820ef121b38479f2479c03c12c69f940f5fa33
Author:     Zhenlei Huang <z...@freebsd.org>
AuthorDate: 2023-04-02 16:51:49 +0000
Commit:     Zhenlei Huang <z...@freebsd.org>
CommitDate: 2023-04-02 16:51:49 +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
---
 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 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);
 }
 

Reply via email to