From 2646c3b95731d186ec4b1bff5cd3c1458c6f5139 Mon Sep 17 00:00:00 2001 From: claudio Date: Mon, 22 Jun 2020 09:45:13 +0000 Subject: The interface if_ioctl routine must be called with the NET_LOCK() held. For example the bridge_ioctl() function calls NET_UNLOCK() unconditionally and so calling if_ioctl() without netlock will trigger an assert because of not holding the netlock. Make sure the ioctl handlers are called with the netlock held and drop the lock for the wg(4) specific ioctls in the wg_ioctl handler. This fixes a panic in bridge_ioctl() triggered by ifconfig(8) issuing a SIOCGWG ioctl against bridge(4). This is just a workaround this needs more cleanup but at least this way the panic can not be triggered anymore. OK stsp@, tested by semarie@ --- sys/net/if.c | 9 +-------- sys/net/if_wg.c | 4 ++++ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/sys/net/if.c b/sys/net/if.c index c2d9269114e..fb2f86f4a7c 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if.c,v 1.609 2020/06/22 03:07:57 dlg Exp $ */ +/* $OpenBSD: if.c,v 1.610 2020/06/22 09:45:13 claudio Exp $ */ /* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */ /* @@ -2222,13 +2222,6 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p) /* don't take NET_LOCK because i2c reads take a long time */ error = ((*ifp->if_ioctl)(ifp, cmd, data)); break; - case SIOCSWG: - case SIOCGWG: - /* Don't take NET_LOCK to allow wg(4) to continue to send and - * receive packets while we're loading a large number of - * peers. wg(4) uses its own lock to serialise access. */ - error = ((*ifp->if_ioctl)(ifp, cmd, data)); - break; case SIOCSETKALIVE: case SIOCDIFPHYADDR: diff --git a/sys/net/if_wg.c b/sys/net/if_wg.c index 06ae1a05d73..9d7f35a557b 100644 --- a/sys/net/if_wg.c +++ b/sys/net/if_wg.c @@ -2450,10 +2450,14 @@ wg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) switch (cmd) { case SIOCSWG: + NET_UNLOCK(); ret = wg_ioctl_set(sc, (struct wg_data_io *) data); + NET_LOCK(); break; case SIOCGWG: + NET_UNLOCK(); ret = wg_ioctl_get(sc, (struct wg_data_io *) data); + NET_LOCK(); break; /* Interface IOCTLs */ case SIOCSIFADDR: -- cgit v1.2.3-59-g8ed1b