On Wed, May 30, 2018 at 04:49:15AM +0200, Theo Buehler wrote:
> We can finally get rid of one switch in both, in_ioctl() and
> in_ioctl_change_ifaddr(). With this diff we have one case per ioctl,
> each case dealing with an ioctl starts with a privilege check before any
> global data is modified and the code paths are now straightforward.

Unfortunately, I saw too late that the first version of this diff
contained a mistake in the SIOCSIFADDR case. Let's go more slowly and
let me do this in two steps instead.

Here's the unchanged first part of the diff dealing with in_ioctl()
again. I'll send a fixed version of the second part once this is in.

Index: sys/netinet/in.c
===================================================================
RCS file: /cvs/src/sys/netinet/in.c,v
retrieving revision 1.155
diff -u -p -r1.155 in.c
--- sys/netinet/in.c    31 May 2018 11:49:26 -0000      1.155
+++ sys/netinet/in.c    31 May 2018 12:00:57 -0000
@@ -248,33 +248,28 @@ in_ioctl(u_long cmd, caddr_t data, struc
                }
        }
 
+       if (ia && satosin(&ifr->ifr_addr)->sin_addr.s_addr) {
+               for (; ifa != NULL; ifa = TAILQ_NEXT(ifa, ifa_list)) {
+                       if ((ifa->ifa_addr->sa_family == AF_INET) &&
+                           ifatoia(ifa)->ia_addr.sin_addr.s_addr ==
+                           satosin(&ifr->ifr_addr)->sin_addr.s_addr) {
+                               ia = ifatoia(ifa);
+                               break;
+                       }
+               }
+       }
+       if (ia == NULL) {
+               NET_UNLOCK();
+               return (EADDRNOTAVAIL);
+       }
+
        switch (cmd) {
-       case SIOCSIFNETMASK:
        case SIOCSIFDSTADDR:
-       case SIOCSIFBRDADDR:
                if (!privileged) {
                        error = EPERM;
-                       goto err;
+                       break;
                }
 
-               if (ia && satosin(&ifr->ifr_addr)->sin_addr.s_addr) {
-                       for (; ifa != NULL; ifa = TAILQ_NEXT(ifa, ifa_list)) {
-                               if ((ifa->ifa_addr->sa_family == AF_INET) &&
-                                   ifatoia(ifa)->ia_addr.sin_addr.s_addr ==
-                                   satosin(&ifr->ifr_addr)->sin_addr.s_addr) {
-                                       ia = ifatoia(ifa);
-                                       break;
-                               }
-                       }
-               }
-               if (ia == NULL) {
-                       error = EADDRNOTAVAIL;
-                       goto err;
-               }
-               break;
-       }
-       switch (cmd) {
-       case SIOCSIFDSTADDR:
                if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
                        error = EINVAL;
                        break;
@@ -291,6 +286,11 @@ in_ioctl(u_long cmd, caddr_t data, struc
                break;
 
        case SIOCSIFBRDADDR:
+               if (!privileged) {
+                       error = EPERM;
+                       break;
+               }
+
                if ((ifp->if_flags & IFF_BROADCAST) == 0) {
                        error = EINVAL;
                        break;
@@ -299,12 +299,16 @@ in_ioctl(u_long cmd, caddr_t data, struc
                break;
 
        case SIOCSIFNETMASK:
+               if (!privileged) {
+                       error = EPERM;
+                       break;
+               }
+
                ia->ia_netmask = ia->ia_sockmask.sin_addr.s_addr =
                    ifra->ifra_addr.sin_addr.s_addr;
                break;
        }
 
-err:
        NET_UNLOCK();
        return (error);
 }

Reply via email to