LCOV - code coverage report
Current view: top level - net/core - dev_ioctl.c (source / functions) Hit Total Coverage
Test: gcov_data_raspi2_real_modules_combined.info Lines: 47 161 29.2 %
Date: 2020-09-30 20:25:40 Functions: 4 7 57.1 %
Branches: 24 133 18.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0
       2                 :            : #include <linux/kmod.h>
       3                 :            : #include <linux/netdevice.h>
       4                 :            : #include <linux/etherdevice.h>
       5                 :            : #include <linux/rtnetlink.h>
       6                 :            : #include <linux/net_tstamp.h>
       7                 :            : #include <linux/wireless.h>
       8                 :            : #include <net/wext.h>
       9                 :            : 
      10                 :            : /*
      11                 :            :  *      Map an interface index to its name (SIOCGIFNAME)
      12                 :            :  */
      13                 :            : 
      14                 :            : /*
      15                 :            :  *      We need this ioctl for efficient implementation of the
      16                 :            :  *      if_indextoname() function required by the IPv6 API.  Without
      17                 :            :  *      it, we would have to search all the interfaces to find a
      18                 :            :  *      match.  --pb
      19                 :            :  */
      20                 :            : 
      21                 :            : static int dev_ifname(struct net *net, struct ifreq *ifr)
      22                 :            : {
      23                 :        207 :         ifr->ifr_name[IFNAMSIZ-1] = 0;
      24                 :        207 :         return netdev_get_name(net, ifr->ifr_name, ifr->ifr_ifindex);
      25                 :            : }
      26                 :            : 
      27                 :            : static gifconf_func_t *gifconf_list[NPROTO];
      28                 :            : 
      29                 :            : /**
      30                 :            :  *      register_gifconf        -       register a SIOCGIF handler
      31                 :            :  *      @family: Address family
      32                 :            :  *      @gifconf: Function handler
      33                 :            :  *
      34                 :            :  *      Register protocol dependent address dumping routines. The handler
      35                 :            :  *      that is passed must not be freed or reused until it has been replaced
      36                 :            :  *      by another handler.
      37                 :            :  */
      38                 :        207 : int register_gifconf(unsigned int family, gifconf_func_t *gifconf)
      39                 :            : {
      40         [ +  - ]:        207 :         if (family >= NPROTO)
      41                 :            :                 return -EINVAL;
      42                 :        207 :         gifconf_list[family] = gifconf;
      43                 :        207 :         return 0;
      44                 :            : }
      45                 :            : EXPORT_SYMBOL(register_gifconf);
      46                 :            : 
      47                 :            : /*
      48                 :            :  *      Perform a SIOCGIFCONF call. This structure will change
      49                 :            :  *      size eventually, and there is nothing I can do about it.
      50                 :            :  *      Thus we will need a 'compatibility mode'.
      51                 :            :  */
      52                 :            : 
      53                 :          0 : int dev_ifconf(struct net *net, struct ifconf *ifc, int size)
      54                 :            : {
      55                 :            :         struct net_device *dev;
      56                 :            :         char __user *pos;
      57                 :            :         int len;
      58                 :            :         int total;
      59                 :            :         int i;
      60                 :            : 
      61                 :            :         /*
      62                 :            :          *      Fetch the caller's info block.
      63                 :            :          */
      64                 :            : 
      65                 :          0 :         pos = ifc->ifc_buf;
      66                 :          0 :         len = ifc->ifc_len;
      67                 :            : 
      68                 :            :         /*
      69                 :            :          *      Loop over the interfaces, and write an info block for each.
      70                 :            :          */
      71                 :            : 
      72                 :            :         total = 0;
      73         [ #  # ]:          0 :         for_each_netdev(net, dev) {
      74         [ #  # ]:          0 :                 for (i = 0; i < NPROTO; i++) {
      75         [ #  # ]:          0 :                         if (gifconf_list[i]) {
      76                 :            :                                 int done;
      77         [ #  # ]:          0 :                                 if (!pos)
      78                 :          0 :                                         done = gifconf_list[i](dev, NULL, 0, size);
      79                 :            :                                 else
      80                 :          0 :                                         done = gifconf_list[i](dev, pos + total,
      81                 :            :                                                                len - total, size);
      82         [ #  # ]:          0 :                                 if (done < 0)
      83                 :            :                                         return -EFAULT;
      84                 :          0 :                                 total += done;
      85                 :            :                         }
      86                 :            :                 }
      87                 :            :         }
      88                 :            : 
      89                 :            :         /*
      90                 :            :          *      All done.  Write the updated control block back to the caller.
      91                 :            :          */
      92                 :          0 :         ifc->ifc_len = total;
      93                 :            : 
      94                 :            :         /*
      95                 :            :          *      Both BSD and Solaris return 0 here, so we do too.
      96                 :            :          */
      97                 :          0 :         return 0;
      98                 :            : }
      99                 :            : 
     100                 :            : /*
     101                 :            :  *      Perform the SIOCxIFxxx calls, inside rcu_read_lock()
     102                 :            :  */
     103                 :       3240 : static int dev_ifsioc_locked(struct net *net, struct ifreq *ifr, unsigned int cmd)
     104                 :            : {
     105                 :            :         int err;
     106                 :       3240 :         struct net_device *dev = dev_get_by_name_rcu(net, ifr->ifr_name);
     107                 :            : 
     108         [ +  + ]:       3240 :         if (!dev)
     109                 :            :                 return -ENODEV;
     110                 :            : 
     111   [ +  -  +  -  :       3033 :         switch (cmd) {
             -  +  -  -  
                      - ]
     112                 :            :         case SIOCGIFFLAGS:      /* Get interface flags */
     113                 :        621 :                 ifr->ifr_flags = (short) dev_get_flags(dev);
     114                 :        621 :                 return 0;
     115                 :            : 
     116                 :            :         case SIOCGIFMETRIC:     /* Get the metric on the interface
     117                 :            :                                    (currently unused) */
     118                 :          0 :                 ifr->ifr_metric = 0;
     119                 :          0 :                 return 0;
     120                 :            : 
     121                 :            :         case SIOCGIFMTU:        /* Get the MTU of a device */
     122                 :       2205 :                 ifr->ifr_mtu = dev->mtu;
     123                 :       2205 :                 return 0;
     124                 :            : 
     125                 :            :         case SIOCGIFHWADDR:
     126         [ #  # ]:          0 :                 if (!dev->addr_len)
     127                 :          0 :                         memset(ifr->ifr_hwaddr.sa_data, 0,
     128                 :            :                                sizeof(ifr->ifr_hwaddr.sa_data));
     129                 :            :                 else
     130                 :          0 :                         memcpy(ifr->ifr_hwaddr.sa_data, dev->dev_addr,
     131                 :          0 :                                min(sizeof(ifr->ifr_hwaddr.sa_data),
     132                 :            :                                    (size_t)dev->addr_len));
     133                 :          0 :                 ifr->ifr_hwaddr.sa_family = dev->type;
     134                 :          0 :                 return 0;
     135                 :            : 
     136                 :            :         case SIOCGIFSLAVE:
     137                 :            :                 err = -EINVAL;
     138                 :            :                 break;
     139                 :            : 
     140                 :            :         case SIOCGIFMAP:
     141                 :          0 :                 ifr->ifr_map.mem_start = dev->mem_start;
     142                 :          0 :                 ifr->ifr_map.mem_end   = dev->mem_end;
     143                 :          0 :                 ifr->ifr_map.base_addr = dev->base_addr;
     144                 :          0 :                 ifr->ifr_map.irq       = dev->irq;
     145                 :          0 :                 ifr->ifr_map.dma       = dev->dma;
     146                 :          0 :                 ifr->ifr_map.port      = dev->if_port;
     147                 :          0 :                 return 0;
     148                 :            : 
     149                 :            :         case SIOCGIFINDEX:
     150                 :        207 :                 ifr->ifr_ifindex = dev->ifindex;
     151                 :        207 :                 return 0;
     152                 :            : 
     153                 :            :         case SIOCGIFTXQLEN:
     154                 :          0 :                 ifr->ifr_qlen = dev->tx_queue_len;
     155                 :          0 :                 return 0;
     156                 :            : 
     157                 :            :         default:
     158                 :            :                 /* dev_ioctl() should ensure this case
     159                 :            :                  * is never reached
     160                 :            :                  */
     161                 :          0 :                 WARN_ON(1);
     162                 :            :                 err = -ENOTTY;
     163                 :          0 :                 break;
     164                 :            : 
     165                 :            :         }
     166                 :          0 :         return err;
     167                 :            : }
     168                 :            : 
     169                 :          0 : static int net_hwtstamp_validate(struct ifreq *ifr)
     170                 :            : {
     171                 :            :         struct hwtstamp_config cfg;
     172                 :            :         enum hwtstamp_tx_types tx_type;
     173                 :            :         enum hwtstamp_rx_filters rx_filter;
     174                 :            :         int tx_type_valid = 0;
     175                 :            :         int rx_filter_valid = 0;
     176                 :            : 
     177         [ #  # ]:          0 :         if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
     178                 :            :                 return -EFAULT;
     179                 :            : 
     180         [ #  # ]:          0 :         if (cfg.flags) /* reserved for future extensions */
     181                 :            :                 return -EINVAL;
     182                 :            : 
     183                 :          0 :         tx_type = cfg.tx_type;
     184                 :          0 :         rx_filter = cfg.rx_filter;
     185                 :            : 
     186         [ #  # ]:          0 :         switch (tx_type) {
     187                 :            :         case HWTSTAMP_TX_OFF:
     188                 :            :         case HWTSTAMP_TX_ON:
     189                 :            :         case HWTSTAMP_TX_ONESTEP_SYNC:
     190                 :            :                 tx_type_valid = 1;
     191                 :          0 :                 break;
     192                 :            :         }
     193                 :            : 
     194         [ #  # ]:          0 :         switch (rx_filter) {
     195                 :            :         case HWTSTAMP_FILTER_NONE:
     196                 :            :         case HWTSTAMP_FILTER_ALL:
     197                 :            :         case HWTSTAMP_FILTER_SOME:
     198                 :            :         case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
     199                 :            :         case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
     200                 :            :         case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
     201                 :            :         case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
     202                 :            :         case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
     203                 :            :         case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
     204                 :            :         case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
     205                 :            :         case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
     206                 :            :         case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
     207                 :            :         case HWTSTAMP_FILTER_PTP_V2_EVENT:
     208                 :            :         case HWTSTAMP_FILTER_PTP_V2_SYNC:
     209                 :            :         case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
     210                 :            :         case HWTSTAMP_FILTER_NTP_ALL:
     211                 :            :                 rx_filter_valid = 1;
     212                 :          0 :                 break;
     213                 :            :         }
     214                 :            : 
     215         [ #  # ]:          0 :         if (!tx_type_valid || !rx_filter_valid)
     216                 :            :                 return -ERANGE;
     217                 :            : 
     218                 :          0 :         return 0;
     219                 :            : }
     220                 :            : 
     221                 :            : /*
     222                 :            :  *      Perform the SIOCxIFxxx calls, inside rtnl_lock()
     223                 :            :  */
     224                 :          0 : static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd)
     225                 :            : {
     226                 :            :         int err;
     227                 :          0 :         struct net_device *dev = __dev_get_by_name(net, ifr->ifr_name);
     228                 :            :         const struct net_device_ops *ops;
     229                 :            : 
     230         [ #  # ]:          0 :         if (!dev)
     231                 :            :                 return -ENODEV;
     232                 :            : 
     233                 :          0 :         ops = dev->netdev_ops;
     234                 :            : 
     235   [ #  #  #  #  :          0 :         switch (cmd) {
          #  #  #  #  #  
                #  #  # ]
     236                 :            :         case SIOCSIFFLAGS:      /* Set interface flags */
     237                 :          0 :                 return dev_change_flags(dev, ifr->ifr_flags, NULL);
     238                 :            : 
     239                 :            :         case SIOCSIFMETRIC:     /* Set the metric on the interface
     240                 :            :                                    (currently unused) */
     241                 :            :                 return -EOPNOTSUPP;
     242                 :            : 
     243                 :            :         case SIOCSIFMTU:        /* Set the MTU of a device */
     244                 :          0 :                 return dev_set_mtu(dev, ifr->ifr_mtu);
     245                 :            : 
     246                 :            :         case SIOCSIFHWADDR:
     247         [ #  # ]:          0 :                 if (dev->addr_len > sizeof(struct sockaddr))
     248                 :            :                         return -EINVAL;
     249                 :          0 :                 return dev_set_mac_address(dev, &ifr->ifr_hwaddr, NULL);
     250                 :            : 
     251                 :            :         case SIOCSIFHWBROADCAST:
     252         [ #  # ]:          0 :                 if (ifr->ifr_hwaddr.sa_family != dev->type)
     253                 :            :                         return -EINVAL;
     254                 :          0 :                 memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data,
     255                 :          0 :                        min(sizeof(ifr->ifr_hwaddr.sa_data),
     256                 :            :                            (size_t)dev->addr_len));
     257                 :          0 :                 call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
     258                 :          0 :                 return 0;
     259                 :            : 
     260                 :            :         case SIOCSIFMAP:
     261         [ #  # ]:          0 :                 if (ops->ndo_set_config) {
     262         [ #  # ]:          0 :                         if (!netif_device_present(dev))
     263                 :            :                                 return -ENODEV;
     264                 :          0 :                         return ops->ndo_set_config(dev, &ifr->ifr_map);
     265                 :            :                 }
     266                 :            :                 return -EOPNOTSUPP;
     267                 :            : 
     268                 :            :         case SIOCADDMULTI:
     269   [ #  #  #  # ]:          0 :                 if (!ops->ndo_set_rx_mode ||
     270                 :          0 :                     ifr->ifr_hwaddr.sa_family != AF_UNSPEC)
     271                 :            :                         return -EINVAL;
     272         [ #  # ]:          0 :                 if (!netif_device_present(dev))
     273                 :            :                         return -ENODEV;
     274                 :          0 :                 return dev_mc_add_global(dev, ifr->ifr_hwaddr.sa_data);
     275                 :            : 
     276                 :            :         case SIOCDELMULTI:
     277   [ #  #  #  # ]:          0 :                 if (!ops->ndo_set_rx_mode ||
     278                 :          0 :                     ifr->ifr_hwaddr.sa_family != AF_UNSPEC)
     279                 :            :                         return -EINVAL;
     280         [ #  # ]:          0 :                 if (!netif_device_present(dev))
     281                 :            :                         return -ENODEV;
     282                 :          0 :                 return dev_mc_del_global(dev, ifr->ifr_hwaddr.sa_data);
     283                 :            : 
     284                 :            :         case SIOCSIFTXQLEN:
     285         [ #  # ]:          0 :                 if (ifr->ifr_qlen < 0)
     286                 :            :                         return -EINVAL;
     287                 :          0 :                 return dev_change_tx_queue_len(dev, ifr->ifr_qlen);
     288                 :            : 
     289                 :            :         case SIOCSIFNAME:
     290                 :          0 :                 ifr->ifr_newname[IFNAMSIZ-1] = '\0';
     291                 :          0 :                 return dev_change_name(dev, ifr->ifr_newname);
     292                 :            : 
     293                 :            :         case SIOCSHWTSTAMP:
     294                 :          0 :                 err = net_hwtstamp_validate(ifr);
     295         [ #  # ]:          0 :                 if (err)
     296                 :            :                         return err;
     297                 :            :                 /* fall through */
     298                 :            : 
     299                 :            :         /*
     300                 :            :          *      Unknown or private ioctl
     301                 :            :          */
     302                 :            :         default:
     303         [ #  # ]:          0 :                 if ((cmd >= SIOCDEVPRIVATE &&
     304                 :          0 :                     cmd <= SIOCDEVPRIVATE + 15) ||
     305                 :          0 :                     cmd == SIOCBONDENSLAVE ||
     306         [ #  # ]:          0 :                     cmd == SIOCBONDRELEASE ||
     307                 :            :                     cmd == SIOCBONDSETHWADDR ||
     308         [ #  # ]:          0 :                     cmd == SIOCBONDSLAVEINFOQUERY ||
     309                 :            :                     cmd == SIOCBONDINFOQUERY ||
     310         [ #  # ]:          0 :                     cmd == SIOCBONDCHANGEACTIVE ||
     311                 :          0 :                     cmd == SIOCGMIIPHY ||
     312         [ #  # ]:          0 :                     cmd == SIOCGMIIREG ||
     313                 :            :                     cmd == SIOCSMIIREG ||
     314         [ #  # ]:          0 :                     cmd == SIOCBRADDIF ||
     315                 :            :                     cmd == SIOCBRDELIF ||
     316         [ #  # ]:          0 :                     cmd == SIOCSHWTSTAMP ||
     317         [ #  # ]:          0 :                     cmd == SIOCGHWTSTAMP ||
     318                 :            :                     cmd == SIOCWANDEV) {
     319                 :            :                         err = -EOPNOTSUPP;
     320         [ #  # ]:          0 :                         if (ops->ndo_do_ioctl) {
     321         [ #  # ]:          0 :                                 if (netif_device_present(dev))
     322                 :          0 :                                         err = ops->ndo_do_ioctl(dev, ifr, cmd);
     323                 :            :                                 else
     324                 :            :                                         err = -ENODEV;
     325                 :            :                         }
     326                 :            :                 } else
     327                 :            :                         err = -EINVAL;
     328                 :            : 
     329                 :            :         }
     330                 :          0 :         return err;
     331                 :            : }
     332                 :            : 
     333                 :            : /**
     334                 :            :  *      dev_load        - load a network module
     335                 :            :  *      @net: the applicable net namespace
     336                 :            :  *      @name: name of interface
     337                 :            :  *
     338                 :            :  *      If a network interface is not present and the process has suitable
     339                 :            :  *      privileges this function loads the module. If module loading is not
     340                 :            :  *      available in this kernel then it becomes a nop.
     341                 :            :  */
     342                 :            : 
     343                 :       4275 : void dev_load(struct net *net, const char *name)
     344                 :            : {
     345                 :            :         struct net_device *dev;
     346                 :            :         int no_module;
     347                 :            : 
     348                 :            :         rcu_read_lock();
     349                 :       4275 :         dev = dev_get_by_name_rcu(net, name);
     350                 :            :         rcu_read_unlock();
     351                 :            : 
     352                 :       4275 :         no_module = !dev;
     353   [ +  +  +  - ]:       4275 :         if (no_module && capable(CAP_NET_ADMIN))
     354                 :        414 :                 no_module = request_module("netdev-%s", name);
     355   [ +  +  +  - ]:       4275 :         if (no_module && capable(CAP_SYS_MODULE))
     356                 :        414 :                 request_module("%s", name);
     357                 :       4275 : }
     358                 :            : EXPORT_SYMBOL(dev_load);
     359                 :            : 
     360                 :            : /*
     361                 :            :  *      This function handles all "interface"-type I/O control requests. The actual
     362                 :            :  *      'doing' part of this is dev_ifsioc above.
     363                 :            :  */
     364                 :            : 
     365                 :            : /**
     366                 :            :  *      dev_ioctl       -       network device ioctl
     367                 :            :  *      @net: the applicable net namespace
     368                 :            :  *      @cmd: command to issue
     369                 :            :  *      @ifr: pointer to a struct ifreq in user space
     370                 :            :  *      @need_copyout: whether or not copy_to_user() should be called
     371                 :            :  *
     372                 :            :  *      Issue ioctl functions to devices. This is normally called by the
     373                 :            :  *      user space syscall interfaces but can sometimes be useful for
     374                 :            :  *      other purposes. The return value is the return from the syscall if
     375                 :            :  *      positive or a negative errno code on error.
     376                 :            :  */
     377                 :            : 
     378                 :      11127 : int dev_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr, bool *need_copyout)
     379                 :            : {
     380                 :            :         int ret;
     381                 :            :         char *colon;
     382                 :            : 
     383         [ +  - ]:      11127 :         if (need_copyout)
     384                 :      11127 :                 *need_copyout = true;
     385         [ +  + ]:      11127 :         if (cmd == SIOCGIFNAME)
     386                 :        207 :                 return dev_ifname(net, ifr);
     387                 :            : 
     388                 :      10920 :         ifr->ifr_name[IFNAMSIZ-1] = 0;
     389                 :            : 
     390                 :      10920 :         colon = strchr(ifr->ifr_name, ':');
     391         [ +  + ]:      10920 :         if (colon)
     392                 :         26 :                 *colon = 0;
     393                 :            : 
     394                 :            :         /*
     395                 :            :          *      See which interface the caller is talking about.
     396                 :            :          */
     397                 :            : 
     398   [ +  +  -  -  :      10920 :         switch (cmd) {
             -  -  +  - ]
     399                 :            :         /*
     400                 :            :          *      These ioctl calls:
     401                 :            :          *      - can be done by all.
     402                 :            :          *      - atomic and do not require locking.
     403                 :            :          *      - return a value
     404                 :            :          */
     405                 :            :         case SIOCGIFFLAGS:
     406                 :            :         case SIOCGIFMETRIC:
     407                 :            :         case SIOCGIFMTU:
     408                 :            :         case SIOCGIFHWADDR:
     409                 :            :         case SIOCGIFSLAVE:
     410                 :            :         case SIOCGIFMAP:
     411                 :            :         case SIOCGIFINDEX:
     412                 :            :         case SIOCGIFTXQLEN:
     413                 :       3240 :                 dev_load(net, ifr->ifr_name);
     414                 :            :                 rcu_read_lock();
     415                 :       3240 :                 ret = dev_ifsioc_locked(net, ifr, cmd);
     416                 :            :                 rcu_read_unlock();
     417         [ -  + ]:       3240 :                 if (colon)
     418                 :          0 :                         *colon = ':';
     419                 :       3240 :                 return ret;
     420                 :            : 
     421                 :            :         case SIOCETHTOOL:
     422                 :        414 :                 dev_load(net, ifr->ifr_name);
     423                 :        414 :                 rtnl_lock();
     424                 :        414 :                 ret = dev_ethtool(net, ifr);
     425                 :        414 :                 rtnl_unlock();
     426         [ -  + ]:        414 :                 if (colon)
     427                 :          0 :                         *colon = ':';
     428                 :        414 :                 return ret;
     429                 :            : 
     430                 :            :         /*
     431                 :            :          *      These ioctl calls:
     432                 :            :          *      - require superuser power.
     433                 :            :          *      - require strict serialization.
     434                 :            :          *      - return a value
     435                 :            :          */
     436                 :            :         case SIOCGMIIPHY:
     437                 :            :         case SIOCGMIIREG:
     438                 :            :         case SIOCSIFNAME:
     439                 :          0 :                 dev_load(net, ifr->ifr_name);
     440         [ #  # ]:          0 :                 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
     441                 :            :                         return -EPERM;
     442                 :          0 :                 rtnl_lock();
     443                 :          0 :                 ret = dev_ifsioc(net, ifr, cmd);
     444                 :          0 :                 rtnl_unlock();
     445         [ #  # ]:          0 :                 if (colon)
     446                 :          0 :                         *colon = ':';
     447                 :          0 :                 return ret;
     448                 :            : 
     449                 :            :         /*
     450                 :            :          *      These ioctl calls:
     451                 :            :          *      - require superuser power.
     452                 :            :          *      - require strict serialization.
     453                 :            :          *      - do not return a value
     454                 :            :          */
     455                 :            :         case SIOCSIFMAP:
     456                 :            :         case SIOCSIFTXQLEN:
     457         [ #  # ]:          0 :                 if (!capable(CAP_NET_ADMIN))
     458                 :            :                         return -EPERM;
     459                 :            :                 /* fall through */
     460                 :            :         /*
     461                 :            :          *      These ioctl calls:
     462                 :            :          *      - require local superuser power.
     463                 :            :          *      - require strict serialization.
     464                 :            :          *      - do not return a value
     465                 :            :          */
     466                 :            :         case SIOCSIFFLAGS:
     467                 :            :         case SIOCSIFMETRIC:
     468                 :            :         case SIOCSIFMTU:
     469                 :            :         case SIOCSIFHWADDR:
     470                 :            :         case SIOCSIFSLAVE:
     471                 :            :         case SIOCADDMULTI:
     472                 :            :         case SIOCDELMULTI:
     473                 :            :         case SIOCSIFHWBROADCAST:
     474                 :            :         case SIOCSMIIREG:
     475                 :            :         case SIOCBONDENSLAVE:
     476                 :            :         case SIOCBONDRELEASE:
     477                 :            :         case SIOCBONDSETHWADDR:
     478                 :            :         case SIOCBONDCHANGEACTIVE:
     479                 :            :         case SIOCBRADDIF:
     480                 :            :         case SIOCBRDELIF:
     481                 :            :         case SIOCSHWTSTAMP:
     482         [ #  # ]:          0 :                 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
     483                 :            :                         return -EPERM;
     484                 :            :                 /* fall through */
     485                 :            :         case SIOCBONDSLAVEINFOQUERY:
     486                 :            :         case SIOCBONDINFOQUERY:
     487                 :          0 :                 dev_load(net, ifr->ifr_name);
     488                 :          0 :                 rtnl_lock();
     489                 :          0 :                 ret = dev_ifsioc(net, ifr, cmd);
     490                 :          0 :                 rtnl_unlock();
     491         [ #  # ]:          0 :                 if (need_copyout)
     492                 :          0 :                         *need_copyout = false;
     493                 :          0 :                 return ret;
     494                 :            : 
     495                 :            :         case SIOCGIFMEM:
     496                 :            :                 /* Get the per device memory space. We can add this but
     497                 :            :                  * currently do not support it */
     498                 :            :         case SIOCSIFMEM:
     499                 :            :                 /* Set the per device memory buffer space.
     500                 :            :                  * Not applicable in our case */
     501                 :            :         case SIOCSIFLINK:
     502                 :            :                 return -ENOTTY;
     503                 :            : 
     504                 :            :         /*
     505                 :            :          *      Unknown or private ioctl.
     506                 :            :          */
     507                 :            :         default:
     508         [ +  - ]:      14532 :                 if (cmd == SIOCWANDEV ||
     509         [ -  + ]:      14532 :                     cmd == SIOCGHWTSTAMP ||
     510                 :       7266 :                     (cmd >= SIOCDEVPRIVATE &&
     511                 :            :                      cmd <= SIOCDEVPRIVATE + 15)) {
     512                 :          0 :                         dev_load(net, ifr->ifr_name);
     513                 :          0 :                         rtnl_lock();
     514                 :          0 :                         ret = dev_ifsioc(net, ifr, cmd);
     515                 :          0 :                         rtnl_unlock();
     516                 :          0 :                         return ret;
     517                 :            :                 }
     518                 :            :                 return -ENOTTY;
     519                 :            :         }
     520                 :            : }

Generated by: LCOV version 1.14