diff options
| author | Gleb Smirnoff <glebius@FreeBSD.org> | 2024-05-06 22:25:53 +0000 |
|---|---|---|
| committer | Gleb Smirnoff <glebius@FreeBSD.org> | 2024-05-06 22:27:32 +0000 |
| commit | fadbb6f85a2ea6d804c12848e3fcfdb6f62fc039 (patch) | |
| tree | 1ee6e836ebabbe7b9d07fba180ceb7196094bb45 | |
| parent | 570685971c6ad30c75103453a38fdb2dff432bef (diff) | |
lagg: remove use of net epoch in the ioctl paths
Rely on LAGG_SLOCK() instead. The use of network epoch(9) here was added
in 6573d7580b851 (later tidied by 87bf9b9cbeebc) as a large sweep that
blindly substituted blocking kernel primitives with epoch(9). In these
particular code paths use of epoch(9) is incorrect and doesn't provide any
protection against a stale pointer. Recent fix 48698ead6ff0, which should
actually have removed the epoch use, created a potential sleeping in epoch
problem.
| -rw-r--r-- | sys/net/if_lagg.c | 33 |
1 files changed, 11 insertions, 22 deletions
diff --git a/sys/net/if_lagg.c b/sys/net/if_lagg.c index 1f169ee32696..bb882ac819ad 100644 --- a/sys/net/if_lagg.c +++ b/sys/net/if_lagg.c @@ -1015,7 +1015,6 @@ lagg_port_destroy(struct lagg_port *lp, int rundelport) static int lagg_port_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { - struct epoch_tracker et; struct lagg_reqport *rp = (struct lagg_reqport *)data; struct lagg_softc *sc; struct lagg_port *lp = NULL; @@ -1040,17 +1039,13 @@ lagg_port_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) break; } - NET_EPOCH_ENTER(et); - if ((lp = ifp->if_lagg) == NULL || lp->lp_softc != sc) { - error = ENOENT; - NET_EPOCH_EXIT(et); - break; - } - LAGG_SLOCK(sc); - lagg_port2req(lp, rp); + if (__predict_true((lp = ifp->if_lagg) != NULL && + lp->lp_softc == sc)) + lagg_port2req(lp, rp); + else + error = ENOENT; /* XXXGL: can happen? */ LAGG_SUNLOCK(sc); - NET_EPOCH_EXIT(et); break; case SIOCSIFCAP: @@ -1350,7 +1345,6 @@ lagg_stop(struct lagg_softc *sc) static int lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { - struct epoch_tracker et; struct lagg_softc *sc = (struct lagg_softc *)ifp->if_softc; struct lagg_reqall *ra = (struct lagg_reqall *)data; struct lagg_reqopts *ro = (struct lagg_reqopts *)data; @@ -1600,21 +1594,16 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) break; } - NET_EPOCH_ENTER(et); - if ((lp = (struct lagg_port *)tpif->if_lagg) == NULL || - lp->lp_softc != sc) { - error = ENOENT; - NET_EPOCH_EXIT(et); - if_rele(tpif); - break; - } - LAGG_SLOCK(sc); - lagg_port2req(lp, rp); + if (__predict_true((lp = tpif->if_lagg) != NULL && + lp->lp_softc == sc)) + lagg_port2req(lp, rp); + else + error = ENOENT; /* XXXGL: can happen? */ LAGG_SUNLOCK(sc); - NET_EPOCH_EXIT(et); if_rele(tpif); break; + case SIOCSLAGGPORT: error = priv_check(td, PRIV_NET_LAGG); if (error) |
