On 09/05/18(Wed) 10:18, Theo Buehler wrote:
> Currently the privilege checks in in_ioctl() happen rather late and for
> SIOCAIFADDR and SIOCDIFADDR after a /* FALLTHROUGH */.  As a further
> small cleanup step in this function, I'd like to move this check to the
> top. This way it's clearer from the start which ioctls are explicitly
> taken care of in this function, that all of them need `privileged' to be
> set, and what happens in the default case.

deraadt@ insisted last year that we should not go this road.  Doing so
makes it easier to forget a security check.

In the end what you want is a single 'case' per ioctl(2). 

> Index: sys/netinet/in.c
> ===================================================================
> RCS file: /var/cvs/src/sys/netinet/in.c,v
> retrieving revision 1.151
> diff -u -p -r1.151 in.c
> --- sys/netinet/in.c  2 May 2018 12:40:52 -0000       1.151
> +++ sys/netinet/in.c  7 May 2018 15:40:04 -0000
> @@ -227,6 +227,17 @@ in_ioctl(u_long cmd, caddr_t data, struc
>       case SIOCGIFDSTADDR:
>       case SIOCGIFBRDADDR:
>               return in_ioctl_get(cmd, data, ifp);
> +     case SIOCAIFADDR:
> +     case SIOCDIFADDR:
> +     case SIOCSIFADDR:
> +     case SIOCSIFNETMASK:
> +     case SIOCSIFDSTADDR:
> +     case SIOCSIFBRDADDR:
> +             if (!privileged)
> +                     return EPERM;
> +             break;
> +     default:
> +             return EOPNOTSUPP;
>       }
>  
>       NET_LOCK();
> @@ -256,11 +267,6 @@ in_ioctl(u_long cmd, caddr_t data, struc
>               }
>               /* FALLTHROUGH */
>       case SIOCSIFADDR:
> -             if (!privileged) {
> -                     error = EPERM;
> -                     goto err;
> -             }
> -
>               if (ia == NULL) {
>                       ia = malloc(sizeof *ia, M_IFADDR, M_WAITOK | M_ZERO);
>                       ia->ia_addr.sin_family = AF_INET;
> @@ -283,11 +289,6 @@ in_ioctl(u_long cmd, caddr_t data, struc
>       case SIOCSIFNETMASK:
>       case SIOCSIFDSTADDR:
>       case SIOCSIFBRDADDR:
> -             if (!privileged) {
> -                     error = EPERM;
> -                     goto err;
> -             }
> -
>               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) &&
> @@ -389,10 +390,6 @@ in_ioctl(u_long cmd, caddr_t data, struc
>                */
>               in_purgeaddr(&ia->ia_ifa);
>               dohooks(ifp->if_addrhooks, 0);
> -             break;
> -
> -     default:
> -             error = EOPNOTSUPP;
>               break;
>       }
>  
> 

Reply via email to