Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 24 Jun 2024 14:53:52 GMT
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 02cbf9ebf110 - main - lagg: Fix a teardown race
Message-ID:  <202406241453.45OErqHO004700@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=02cbf9ebf110c94ec9e60f0801716ff0a75e55e5

commit 02cbf9ebf110c94ec9e60f0801716ff0a75e55e5
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2024-06-24 14:47:29 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2024-06-24 14:47:29 +0000

    lagg: Fix a teardown race
    
    When a lagg interface is destroyed, it destroys all of the lagg ports,
    which triggers an asynchronous link state change handler.  This in turn
    may generate a netlink message, a portion of which requires netlink to
    invoke the SIOCGIFMEDIA ioctl of the lagg interface, which involves
    scanning the list of interface media.  This list is not internally
    locked, it requires the interface driver to provide some kind of
    synchronization.
    
    Shortly after the link state notification has been raised, the lagg
    interface detaches itself from the network stack.  As a part of this, it
    blocks in order to wait for link state handlers to drain, but before
    that it destroys the interface media list.  Reverse this order of
    operations so that the link state change handlers drain first, avoiding
    a use-after-free that is very occasionally triggered by lagg stress
    tests.  This matches other ethernet drivers in the tree.
    
    MFC after:      2 weeks
---
 sys/net/if_lagg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/net/if_lagg.c b/sys/net/if_lagg.c
index bb882ac819ad..e323bb01b977 100644
--- a/sys/net/if_lagg.c
+++ b/sys/net/if_lagg.c
@@ -643,8 +643,8 @@ lagg_clone_destroy(struct if_clone *ifc, struct ifnet *ifp, uint32_t flags)
 
 	switch (ifp->if_type) {
 	case IFT_ETHER:
-		ifmedia_removeall(&sc->sc_media);
 		ether_ifdetach(ifp);
+		ifmedia_removeall(&sc->sc_media);
 		break;
 	case IFT_INFINIBAND:
 		infiniband_ifdetach(ifp);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202406241453.45OErqHO004700>