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