On 09/10/17(Mon) 16:34, Martin Pieuchot wrote:
> Here's a small cleanup to make it easy to push the NET_LOCK() further
> down.
> 
> Diff below factorize all ioctl requests need root privileges in one
> switch () block.
> 
> It moves SIOCIFAFATTACH/SIOCIFAFDETACH where it belongs, to the block
> that keeps track of the timestamps of the last change.
> 
> It gets rid of unnecessary `sdl' variable.

Similar diff without factorizing privilege checks, deraadt@ pointed out
it is too fragile.

ok?

Index: net/if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.513
diff -u -p -r1.513 if.c
--- net/if.c    9 Oct 2017 08:35:38 -0000       1.513
+++ net/if.c    10 Oct 2017 13:46:43 -0000
@@ -1816,10 +1816,9 @@ int
 ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
 {
        struct ifnet *ifp;
-       struct ifreq *ifr;
-       struct sockaddr_dl *sdl;
+       struct ifreq *ifr = (struct ifreq *)data;
        struct ifgroupreq *ifgr;
-       struct if_afreq *ifar;
+       struct if_afreq *ifar = (struct if_afreq *)data;
        char ifdescrbuf[IFDESCRSIZE];
        char ifrtlabelbuf[RTLABEL_LEN];
        int s, error = 0, oif_xflags;
@@ -1828,13 +1827,8 @@ ifioctl(struct socket *so, u_long cmd, c
        const char *label;
 
        switch (cmd) {
-
        case SIOCGIFCONF:
                return (ifconf(cmd, data));
-       }
-       ifr = (struct ifreq *)data;
-
-       switch (cmd) {
        case SIOCIFCREATE:
        case SIOCIFDESTROY:
                if ((error = suser(p, 0)) != 0)
@@ -1852,15 +1846,19 @@ ifioctl(struct socket *so, u_long cmd, c
                if ((error = suser(p, 0)) != 0)
                        return (error);
                return (if_setgroupattribs(data));
+       }
+
+       ifp = ifunit(ifr->ifr_name);
+       if (ifp == NULL)
+               return (ENXIO);
+       oif_flags = ifp->if_flags;
+       oif_xflags = ifp->if_xflags;
+
+       switch (cmd) {
        case SIOCIFAFATTACH:
        case SIOCIFAFDETACH:
                if ((error = suser(p, 0)) != 0)
                        return (error);
-               ifar = (struct if_afreq *)data;
-               if ((ifp = ifunit(ifar->ifar_name)) == NULL)
-                       return (ENXIO);
-               oif_flags = ifp->if_flags;
-               oif_xflags = ifp->if_xflags;
                switch (ifar->ifar_af) {
                case AF_INET:
                        /* attach is a noop for AF_INET */
@@ -1878,16 +1876,7 @@ ifioctl(struct socket *so, u_long cmd, c
                default:
                        return (EAFNOSUPPORT);
                }
-               if (oif_flags != ifp->if_flags || oif_xflags != ifp->if_xflags)
-                       rtm_ifchg(ifp);
-               return (error);
-       }
-
-       ifp = ifunit(ifr->ifr_name);
-       if (ifp == 0)
-               return (ENXIO);
-       oif_flags = ifp->if_flags;
-       switch (cmd) {
+               break;
 
        case SIOCGIFFLAGS:
                ifr->ifr_flags = ifp->if_flags;
@@ -2002,7 +1991,6 @@ ifioctl(struct socket *so, u_long cmd, c
 
                ifp->if_xflags = (ifp->if_xflags & IFXF_CANTCHANGE) |
                        (ifr->ifr_flags & ~IFXF_CANTCHANGE);
-               rtm_ifchg(ifp);
                break;
 
        case SIOCSIFMETRIC:
@@ -2140,8 +2128,7 @@ ifioctl(struct socket *so, u_long cmd, c
        case SIOCSIFLLADDR:
                if ((error = suser(p, 0)))
                        return (error);
-               sdl = ifp->if_sadl;
-               if (sdl == NULL)
+               if (ifp->if_sadl == NULL)
                        return (EINVAL);
                if (ifr->ifr_addr.sa_len != ETHER_ADDR_LEN)
                        return (EINVAL);
@@ -2182,6 +2169,9 @@ ifioctl(struct socket *so, u_long cmd, c
                        (struct mbuf *) ifp, p));
                break;
        }
+
+       if (oif_flags != ifp->if_flags || oif_xflags != ifp->if_xflags)
+               rtm_ifchg(ifp);
 
        if (((oif_flags ^ ifp->if_flags) & IFF_UP) != 0)
                getmicrotime(&ifp->if_lastchange);

Reply via email to