Push kernel lock from ifioctl() into ifioctl_get()
authorkn <kn@openbsd.org>
Wed, 9 Nov 2022 13:08:36 +0000 (13:08 +0000)
committerkn <kn@openbsd.org>
Wed, 9 Nov 2022 13:08:36 +0000 (13:08 +0000)
Recommit these two together:
- r1.667 "Push kernel lock into ifioctl_get()"
  locked before the switch() without unlocking in its cases
- r1.668 "Push kernel lock inside ifioctl_get()"
  locked cases individually, as intended

I messed up splitting commits, but of course, Hrvoje managed to test a
CVS checkout right inbetween those two.

OK mpi mvs

sys/net/if.c

index 9d4dc8c..c740072 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if.c,v 1.673 2022/11/09 10:41:18 dlg Exp $    */
+/*     $OpenBSD: if.c,v 1.674 2022/11/09 13:08:36 kn Exp $     */
 /*     $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $  */
 
 /*
@@ -1933,9 +1933,7 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
        case SIOCGIFRDOMAIN:
        case SIOCGIFGROUP:
        case SIOCGIFLLPRIO:
-               KERNEL_LOCK();
                error = ifioctl_get(cmd, data);
-               KERNEL_UNLOCK();
                return (error);
        }
 
@@ -2384,33 +2382,47 @@ ifioctl_get(u_long cmd, caddr_t data)
 
        switch(cmd) {
        case SIOCGIFCONF:
+               KERNEL_LOCK();
                NET_LOCK_SHARED();
                error = ifconf(data);
                NET_UNLOCK_SHARED();
+               KERNEL_UNLOCK();
                return (error);
        case SIOCIFGCLONERS:
+               KERNEL_LOCK();
                error = if_clone_list((struct if_clonereq *)data);
+               KERNEL_UNLOCK();
                return (error);
        case SIOCGIFGMEMB:
+               KERNEL_LOCK();
                NET_LOCK_SHARED();
                error = if_getgroupmembers(data);
                NET_UNLOCK_SHARED();
+               KERNEL_UNLOCK();
                return (error);
        case SIOCGIFGATTR:
+               KERNEL_LOCK();
                NET_LOCK_SHARED();
                error = if_getgroupattribs(data);
                NET_UNLOCK_SHARED();
+               KERNEL_UNLOCK();
                return (error);
        case SIOCGIFGLIST:
+               KERNEL_LOCK();
                NET_LOCK_SHARED();
                error = if_getgrouplist(data);
                NET_UNLOCK_SHARED();
+               KERNEL_UNLOCK();
                return (error);
        }
 
+       KERNEL_LOCK();
+
        ifp = if_unit(ifr->ifr_name);
-       if (ifp == NULL)
+       if (ifp == NULL) {
+               KERNEL_UNLOCK();
                return (ENXIO);
+       }
 
        NET_LOCK_SHARED();
 
@@ -2482,6 +2494,8 @@ ifioctl_get(u_long cmd, caddr_t data)
 
        NET_UNLOCK_SHARED();
 
+       KERNEL_UNLOCK();
+
        if_put(ifp);
 
        return (error);