LCOV - code coverage report
Current view: top level - net/netlink - genetlink.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 181 723 25.0 %
Date: 2021-04-22 12:43:58 Functions: 17 49 34.7 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  * NETLINK      Generic Netlink Family
       4             :  *
       5             :  *              Authors:        Jamal Hadi Salim
       6             :  *                              Thomas Graf <tgraf@suug.ch>
       7             :  *                              Johannes Berg <johannes@sipsolutions.net>
       8             :  */
       9             : 
      10             : #include <linux/module.h>
      11             : #include <linux/kernel.h>
      12             : #include <linux/slab.h>
      13             : #include <linux/errno.h>
      14             : #include <linux/types.h>
      15             : #include <linux/socket.h>
      16             : #include <linux/string.h>
      17             : #include <linux/skbuff.h>
      18             : #include <linux/mutex.h>
      19             : #include <linux/bitmap.h>
      20             : #include <linux/rwsem.h>
      21             : #include <linux/idr.h>
      22             : #include <net/sock.h>
      23             : #include <net/genetlink.h>
      24             : 
      25             : static DEFINE_MUTEX(genl_mutex); /* serialization of message processing */
      26             : static DECLARE_RWSEM(cb_lock);
      27             : 
      28             : atomic_t genl_sk_destructing_cnt = ATOMIC_INIT(0);
      29             : DECLARE_WAIT_QUEUE_HEAD(genl_sk_destructing_waitq);
      30             : 
      31           3 : void genl_lock(void)
      32             : {
      33           0 :         mutex_lock(&genl_mutex);
      34           0 : }
      35             : EXPORT_SYMBOL(genl_lock);
      36             : 
      37           3 : void genl_unlock(void)
      38             : {
      39           0 :         mutex_unlock(&genl_mutex);
      40           0 : }
      41             : EXPORT_SYMBOL(genl_unlock);
      42             : 
      43             : #ifdef CONFIG_LOCKDEP
      44           0 : bool lockdep_genl_is_held(void)
      45             : {
      46           0 :         return lockdep_is_held(&genl_mutex);
      47             : }
      48             : EXPORT_SYMBOL(lockdep_genl_is_held);
      49             : #endif
      50             : 
      51           3 : static void genl_lock_all(void)
      52             : {
      53           3 :         down_write(&cb_lock);
      54           3 :         genl_lock();
      55           3 : }
      56             : 
      57           3 : static void genl_unlock_all(void)
      58             : {
      59           3 :         genl_unlock();
      60           3 :         up_write(&cb_lock);
      61           3 : }
      62             : 
      63             : static DEFINE_IDR(genl_fam_idr);
      64             : 
      65             : /*
      66             :  * Bitmap of multicast groups that are currently in use.
      67             :  *
      68             :  * To avoid an allocation at boot of just one unsigned long,
      69             :  * declare it global instead.
      70             :  * Bit 0 is marked as already used since group 0 is invalid.
      71             :  * Bit 1 is marked as already used since the drop-monitor code
      72             :  * abuses the API and thinks it can statically use group 1.
      73             :  * That group will typically conflict with other groups that
      74             :  * any proper users use.
      75             :  * Bit 16 is marked as used since it's used for generic netlink
      76             :  * and the code no longer marks pre-reserved IDs as used.
      77             :  * Bit 17 is marked as already used since the VFS quota code
      78             :  * also abused this API and relied on family == group ID, we
      79             :  * cater to that by giving it a static family and group ID.
      80             :  * Bit 18 is marked as already used since the PMCRAID driver
      81             :  * did the same thing as the VFS quota code (maybe copied?)
      82             :  */
      83             : static unsigned long mc_group_start = 0x3 | BIT(GENL_ID_CTRL) |
      84             :                                       BIT(GENL_ID_VFS_DQUOT) |
      85             :                                       BIT(GENL_ID_PMCRAID);
      86             : static unsigned long *mc_groups = &mc_group_start;
      87             : static unsigned long mc_groups_longs = 1;
      88             : 
      89             : static int genl_ctrl_event(int event, const struct genl_family *family,
      90             :                            const struct genl_multicast_group *grp,
      91             :                            int grp_id);
      92             : 
      93           0 : static const struct genl_family *genl_family_find_byid(unsigned int id)
      94             : {
      95           0 :         return idr_find(&genl_fam_idr, id);
      96             : }
      97             : 
      98           3 : static const struct genl_family *genl_family_find_byname(char *name)
      99             : {
     100           3 :         const struct genl_family *family;
     101           3 :         unsigned int id;
     102             : 
     103           6 :         idr_for_each_entry(&genl_fam_idr, family, id)
     104           3 :                 if (strcmp(family->name, name) == 0)
     105           0 :                         return family;
     106             : 
     107             :         return NULL;
     108             : }
     109             : 
     110          26 : static int genl_get_cmd_cnt(const struct genl_family *family)
     111             : {
     112          26 :         return family->n_ops + family->n_small_ops;
     113             : }
     114             : 
     115           8 : static void genl_op_from_full(const struct genl_family *family,
     116             :                               unsigned int i, struct genl_ops *op)
     117             : {
     118           8 :         *op = family->ops[i];
     119             : 
     120           8 :         if (!op->maxattr)
     121           0 :                 op->maxattr = family->maxattr;
     122           8 :         if (!op->policy)
     123           0 :                 op->policy = family->policy;
     124           8 : }
     125             : 
     126           0 : static int genl_get_cmd_full(u32 cmd, const struct genl_family *family,
     127             :                              struct genl_ops *op)
     128             : {
     129           0 :         int i;
     130             : 
     131           0 :         for (i = 0; i < family->n_ops; i++)
     132           0 :                 if (family->ops[i].cmd == cmd) {
     133           0 :                         genl_op_from_full(family, i, op);
     134           0 :                         return 0;
     135             :                 }
     136             : 
     137             :         return -ENOENT;
     138             : }
     139             : 
     140           5 : static void genl_op_from_small(const struct genl_family *family,
     141             :                                unsigned int i, struct genl_ops *op)
     142             : {
     143           5 :         memset(op, 0, sizeof(*op));
     144           5 :         op->doit     = family->small_ops[i].doit;
     145           5 :         op->dumpit   = family->small_ops[i].dumpit;
     146           5 :         op->cmd              = family->small_ops[i].cmd;
     147           5 :         op->internal_flags = family->small_ops[i].internal_flags;
     148           5 :         op->flags    = family->small_ops[i].flags;
     149           5 :         op->validate = family->small_ops[i].validate;
     150             : 
     151           5 :         op->maxattr = family->maxattr;
     152           5 :         op->policy = family->policy;
     153           5 : }
     154             : 
     155           0 : static int genl_get_cmd_small(u32 cmd, const struct genl_family *family,
     156             :                               struct genl_ops *op)
     157             : {
     158           0 :         int i;
     159             : 
     160           0 :         for (i = 0; i < family->n_small_ops; i++)
     161           0 :                 if (family->small_ops[i].cmd == cmd) {
     162           0 :                         genl_op_from_small(family, i, op);
     163           0 :                         return 0;
     164             :                 }
     165             : 
     166             :         return -ENOENT;
     167             : }
     168             : 
     169           0 : static int genl_get_cmd(u32 cmd, const struct genl_family *family,
     170             :                         struct genl_ops *op)
     171             : {
     172           0 :         if (!genl_get_cmd_full(cmd, family, op))
     173             :                 return 0;
     174           0 :         return genl_get_cmd_small(cmd, family, op);
     175             : }
     176             : 
     177          13 : static void genl_get_cmd_by_index(unsigned int i,
     178             :                                   const struct genl_family *family,
     179             :                                   struct genl_ops *op)
     180             : {
     181          13 :         if (i < family->n_ops)
     182           8 :                 genl_op_from_full(family, i, op);
     183           5 :         else if (i < family->n_ops + family->n_small_ops)
     184           5 :                 genl_op_from_small(family, i - family->n_ops, op);
     185             :         else
     186           0 :                 WARN_ON_ONCE(1);
     187          13 : }
     188             : 
     189           0 : static int genl_allocate_reserve_groups(int n_groups, int *first_id)
     190             : {
     191           0 :         unsigned long *new_groups;
     192           0 :         int start = 0;
     193           0 :         int i;
     194           0 :         int id;
     195           0 :         bool fits;
     196             : 
     197           0 :         do {
     198           0 :                 if (start == 0)
     199           0 :                         id = find_first_zero_bit(mc_groups,
     200             :                                                  mc_groups_longs *
     201             :                                                  BITS_PER_LONG);
     202             :                 else
     203           0 :                         id = find_next_zero_bit(mc_groups,
     204             :                                                 mc_groups_longs * BITS_PER_LONG,
     205             :                                                 start);
     206             : 
     207           0 :                 fits = true;
     208           0 :                 for (i = id;
     209           0 :                      i < min_t(int, id + n_groups,
     210             :                                mc_groups_longs * BITS_PER_LONG);
     211           0 :                      i++) {
     212           0 :                         if (test_bit(i, mc_groups)) {
     213             :                                 start = i;
     214             :                                 fits = false;
     215             :                                 break;
     216             :                         }
     217             :                 }
     218             : 
     219           0 :                 if (id + n_groups > mc_groups_longs * BITS_PER_LONG) {
     220           0 :                         unsigned long new_longs = mc_groups_longs +
     221           0 :                                                   BITS_TO_LONGS(n_groups);
     222           0 :                         size_t nlen = new_longs * sizeof(unsigned long);
     223             : 
     224           0 :                         if (mc_groups == &mc_group_start) {
     225           0 :                                 new_groups = kzalloc(nlen, GFP_KERNEL);
     226           0 :                                 if (!new_groups)
     227             :                                         return -ENOMEM;
     228           0 :                                 mc_groups = new_groups;
     229           0 :                                 *mc_groups = mc_group_start;
     230             :                         } else {
     231           0 :                                 new_groups = krealloc(mc_groups, nlen,
     232             :                                                       GFP_KERNEL);
     233           0 :                                 if (!new_groups)
     234             :                                         return -ENOMEM;
     235           0 :                                 mc_groups = new_groups;
     236           0 :                                 for (i = 0; i < BITS_TO_LONGS(n_groups); i++)
     237           0 :                                         mc_groups[mc_groups_longs + i] = 0;
     238             :                         }
     239           0 :                         mc_groups_longs = new_longs;
     240             :                 }
     241           0 :         } while (!fits);
     242             : 
     243           0 :         for (i = id; i < id + n_groups; i++)
     244           0 :                 set_bit(i, mc_groups);
     245           0 :         *first_id = id;
     246           0 :         return 0;
     247             : }
     248             : 
     249             : static struct genl_family genl_ctrl;
     250             : 
     251           3 : static int genl_validate_assign_mc_groups(struct genl_family *family)
     252             : {
     253           3 :         int first_id;
     254           3 :         int n_groups = family->n_mcgrps;
     255           3 :         int err = 0, i;
     256           3 :         bool groups_allocated = false;
     257             : 
     258           3 :         if (!n_groups)
     259             :                 return 0;
     260             : 
     261           2 :         for (i = 0; i < n_groups; i++) {
     262           1 :                 const struct genl_multicast_group *grp = &family->mcgrps[i];
     263             : 
     264           1 :                 if (WARN_ON(grp->name[0] == '\0'))
     265             :                         return -EINVAL;
     266           1 :                 if (WARN_ON(memchr(grp->name, '\0', GENL_NAMSIZ) == NULL))
     267             :                         return -EINVAL;
     268             :         }
     269             : 
     270             :         /* special-case our own group and hacks */
     271           1 :         if (family == &genl_ctrl) {
     272           1 :                 first_id = GENL_ID_CTRL;
     273           1 :                 BUG_ON(n_groups != 1);
     274           0 :         } else if (strcmp(family->name, "NET_DM") == 0) {
     275           0 :                 first_id = 1;
     276           0 :                 BUG_ON(n_groups != 1);
     277           0 :         } else if (family->id == GENL_ID_VFS_DQUOT) {
     278           0 :                 first_id = GENL_ID_VFS_DQUOT;
     279           0 :                 BUG_ON(n_groups != 1);
     280           0 :         } else if (family->id == GENL_ID_PMCRAID) {
     281           0 :                 first_id = GENL_ID_PMCRAID;
     282           0 :                 BUG_ON(n_groups != 1);
     283             :         } else {
     284           0 :                 groups_allocated = true;
     285           0 :                 err = genl_allocate_reserve_groups(n_groups, &first_id);
     286           0 :                 if (err)
     287             :                         return err;
     288             :         }
     289             : 
     290           1 :         family->mcgrp_offset = first_id;
     291             : 
     292             :         /* if still initializing, can't and don't need to realloc bitmaps */
     293           1 :         if (!init_net.genl_sock)
     294             :                 return 0;
     295             : 
     296           0 :         if (family->netnsok) {
     297           0 :                 struct net *net;
     298             : 
     299           0 :                 netlink_table_grab();
     300           0 :                 rcu_read_lock();
     301           0 :                 for_each_net_rcu(net) {
     302           0 :                         err = __netlink_change_ngroups(net->genl_sock,
     303             :                                         mc_groups_longs * BITS_PER_LONG);
     304           0 :                         if (err) {
     305             :                                 /*
     306             :                                  * No need to roll back, can only fail if
     307             :                                  * memory allocation fails and then the
     308             :                                  * number of _possible_ groups has been
     309             :                                  * increased on some sockets which is ok.
     310             :                                  */
     311             :                                 break;
     312             :                         }
     313             :                 }
     314           0 :                 rcu_read_unlock();
     315           0 :                 netlink_table_ungrab();
     316             :         } else {
     317           0 :                 err = netlink_change_ngroups(init_net.genl_sock,
     318             :                                              mc_groups_longs * BITS_PER_LONG);
     319             :         }
     320             : 
     321           0 :         if (groups_allocated && err) {
     322           0 :                 for (i = 0; i < family->n_mcgrps; i++)
     323           0 :                         clear_bit(family->mcgrp_offset + i, mc_groups);
     324             :         }
     325             : 
     326             :         return err;
     327             : }
     328             : 
     329           0 : static void genl_unregister_mc_groups(const struct genl_family *family)
     330             : {
     331           0 :         struct net *net;
     332           0 :         int i;
     333             : 
     334           0 :         netlink_table_grab();
     335           0 :         rcu_read_lock();
     336           0 :         for_each_net_rcu(net) {
     337           0 :                 for (i = 0; i < family->n_mcgrps; i++)
     338           0 :                         __netlink_clear_multicast_users(
     339           0 :                                 net->genl_sock, family->mcgrp_offset + i);
     340             :         }
     341           0 :         rcu_read_unlock();
     342           0 :         netlink_table_ungrab();
     343             : 
     344           0 :         for (i = 0; i < family->n_mcgrps; i++) {
     345           0 :                 int grp_id = family->mcgrp_offset + i;
     346             : 
     347           0 :                 if (grp_id != 1)
     348           0 :                         clear_bit(grp_id, mc_groups);
     349           0 :                 genl_ctrl_event(CTRL_CMD_DELMCAST_GRP, family,
     350           0 :                                 &family->mcgrps[i], grp_id);
     351             :         }
     352           0 : }
     353             : 
     354           3 : static int genl_validate_ops(const struct genl_family *family)
     355             : {
     356           3 :         int i, j;
     357             : 
     358           6 :         if (WARN_ON(family->n_ops && !family->ops) ||
     359           6 :             WARN_ON(family->n_small_ops && !family->small_ops))
     360             :                 return -EINVAL;
     361             : 
     362           9 :         for (i = 0; i < genl_get_cmd_cnt(family); i++) {
     363           6 :                 struct genl_ops op;
     364             : 
     365           6 :                 genl_get_cmd_by_index(i, family, &op);
     366           6 :                 if (op.dumpit == NULL && op.doit == NULL)
     367           0 :                         return -EINVAL;
     368           9 :                 for (j = i + 1; j < genl_get_cmd_cnt(family); j++) {
     369           3 :                         struct genl_ops op2;
     370             : 
     371           3 :                         genl_get_cmd_by_index(j, family, &op2);
     372           3 :                         if (op.cmd == op2.cmd)
     373           0 :                                 return -EINVAL;
     374             :                 }
     375             :         }
     376             : 
     377             :         return 0;
     378             : }
     379             : 
     380             : /**
     381             :  * genl_register_family - register a generic netlink family
     382             :  * @family: generic netlink family
     383             :  *
     384             :  * Registers the specified family after validating it first. Only one
     385             :  * family may be registered with the same family name or identifier.
     386             :  *
     387             :  * The family's ops, multicast groups and module pointer must already
     388             :  * be assigned.
     389             :  *
     390             :  * Return 0 on success or a negative error code.
     391             :  */
     392           3 : int genl_register_family(struct genl_family *family)
     393             : {
     394           3 :         int err, i;
     395           3 :         int start = GENL_START_ALLOC, end = GENL_MAX_ID;
     396             : 
     397           3 :         err = genl_validate_ops(family);
     398           3 :         if (err)
     399             :                 return err;
     400             : 
     401           3 :         genl_lock_all();
     402             : 
     403           3 :         if (genl_family_find_byname(family->name)) {
     404           0 :                 err = -EEXIST;
     405           0 :                 goto errout_locked;
     406             :         }
     407             : 
     408             :         /*
     409             :          * Sadly, a few cases need to be special-cased
     410             :          * due to them having previously abused the API
     411             :          * and having used their family ID also as their
     412             :          * multicast group ID, so we use reserved IDs
     413             :          * for both to be sure we can do that mapping.
     414             :          */
     415           3 :         if (family == &genl_ctrl) {
     416             :                 /* and this needs to be special for initial family lookups */
     417             :                 start = end = GENL_ID_CTRL;
     418           2 :         } else if (strcmp(family->name, "pmcraid") == 0) {
     419             :                 start = end = GENL_ID_PMCRAID;
     420           2 :         } else if (strcmp(family->name, "VFS_DQUOT") == 0) {
     421           0 :                 start = end = GENL_ID_VFS_DQUOT;
     422             :         }
     423             : 
     424           3 :         family->id = idr_alloc_cyclic(&genl_fam_idr, family,
     425             :                                       start, end + 1, GFP_KERNEL);
     426           3 :         if (family->id < 0) {
     427           0 :                 err = family->id;
     428           0 :                 goto errout_locked;
     429             :         }
     430             : 
     431           3 :         err = genl_validate_assign_mc_groups(family);
     432           3 :         if (err)
     433           0 :                 goto errout_remove;
     434             : 
     435           3 :         genl_unlock_all();
     436             : 
     437             :         /* send all events */
     438           3 :         genl_ctrl_event(CTRL_CMD_NEWFAMILY, family, NULL, 0);
     439           7 :         for (i = 0; i < family->n_mcgrps; i++)
     440           1 :                 genl_ctrl_event(CTRL_CMD_NEWMCAST_GRP, family,
     441           1 :                                 &family->mcgrps[i], family->mcgrp_offset + i);
     442             : 
     443             :         return 0;
     444             : 
     445           0 : errout_remove:
     446           0 :         idr_remove(&genl_fam_idr, family->id);
     447           0 : errout_locked:
     448           0 :         genl_unlock_all();
     449           0 :         return err;
     450             : }
     451             : EXPORT_SYMBOL(genl_register_family);
     452             : 
     453             : /**
     454             :  * genl_unregister_family - unregister generic netlink family
     455             :  * @family: generic netlink family
     456             :  *
     457             :  * Unregisters the specified family.
     458             :  *
     459             :  * Returns 0 on success or a negative error code.
     460             :  */
     461           0 : int genl_unregister_family(const struct genl_family *family)
     462             : {
     463           0 :         genl_lock_all();
     464             : 
     465           0 :         if (!genl_family_find_byid(family->id)) {
     466           0 :                 genl_unlock_all();
     467           0 :                 return -ENOENT;
     468             :         }
     469             : 
     470           0 :         genl_unregister_mc_groups(family);
     471             : 
     472           0 :         idr_remove(&genl_fam_idr, family->id);
     473             : 
     474           0 :         up_write(&cb_lock);
     475           0 :         wait_event(genl_sk_destructing_waitq,
     476             :                    atomic_read(&genl_sk_destructing_cnt) == 0);
     477           0 :         genl_unlock();
     478             : 
     479           0 :         genl_ctrl_event(CTRL_CMD_DELFAMILY, family, NULL, 0);
     480             : 
     481           0 :         return 0;
     482             : }
     483             : EXPORT_SYMBOL(genl_unregister_family);
     484             : 
     485             : /**
     486             :  * genlmsg_put - Add generic netlink header to netlink message
     487             :  * @skb: socket buffer holding the message
     488             :  * @portid: netlink portid the message is addressed to
     489             :  * @seq: sequence number (usually the one of the sender)
     490             :  * @family: generic netlink family
     491             :  * @flags: netlink message flags
     492             :  * @cmd: generic netlink command
     493             :  *
     494             :  * Returns pointer to user specific header
     495             :  */
     496           2 : void *genlmsg_put(struct sk_buff *skb, u32 portid, u32 seq,
     497             :                   const struct genl_family *family, int flags, u8 cmd)
     498             : {
     499           2 :         struct nlmsghdr *nlh;
     500           2 :         struct genlmsghdr *hdr;
     501             : 
     502           4 :         nlh = nlmsg_put(skb, portid, seq, family->id, GENL_HDRLEN +
     503           2 :                         family->hdrsize, flags);
     504           2 :         if (nlh == NULL)
     505             :                 return NULL;
     506             : 
     507           2 :         hdr = nlmsg_data(nlh);
     508           2 :         hdr->cmd = cmd;
     509           2 :         hdr->version = family->version;
     510           2 :         hdr->reserved = 0;
     511             : 
     512           2 :         return (char *) hdr + GENL_HDRLEN;
     513             : }
     514             : EXPORT_SYMBOL(genlmsg_put);
     515             : 
     516           0 : static struct genl_dumpit_info *genl_dumpit_info_alloc(void)
     517             : {
     518           0 :         return kmalloc(sizeof(struct genl_dumpit_info), GFP_KERNEL);
     519             : }
     520             : 
     521           0 : static void genl_dumpit_info_free(const struct genl_dumpit_info *info)
     522             : {
     523           0 :         kfree(info);
     524             : }
     525             : 
     526             : static struct nlattr **
     527           0 : genl_family_rcv_msg_attrs_parse(const struct genl_family *family,
     528             :                                 struct nlmsghdr *nlh,
     529             :                                 struct netlink_ext_ack *extack,
     530             :                                 const struct genl_ops *ops,
     531             :                                 int hdrlen,
     532             :                                 enum genl_validate_flags no_strict_flag)
     533             : {
     534           0 :         enum netlink_validation validate = ops->validate & no_strict_flag ?
     535           0 :                                            NL_VALIDATE_LIBERAL :
     536             :                                            NL_VALIDATE_STRICT;
     537           0 :         struct nlattr **attrbuf;
     538           0 :         int err;
     539             : 
     540           0 :         if (!ops->maxattr)
     541             :                 return NULL;
     542             : 
     543           0 :         attrbuf = kmalloc_array(ops->maxattr + 1,
     544             :                                 sizeof(struct nlattr *), GFP_KERNEL);
     545           0 :         if (!attrbuf)
     546           0 :                 return ERR_PTR(-ENOMEM);
     547             : 
     548           0 :         err = __nlmsg_parse(nlh, hdrlen, attrbuf, ops->maxattr, ops->policy,
     549             :                             validate, extack);
     550           0 :         if (err) {
     551           0 :                 kfree(attrbuf);
     552           0 :                 return ERR_PTR(err);
     553             :         }
     554             :         return attrbuf;
     555             : }
     556             : 
     557           0 : static void genl_family_rcv_msg_attrs_free(struct nlattr **attrbuf)
     558             : {
     559           0 :         kfree(attrbuf);
     560             : }
     561             : 
     562             : struct genl_start_context {
     563             :         const struct genl_family *family;
     564             :         struct nlmsghdr *nlh;
     565             :         struct netlink_ext_ack *extack;
     566             :         const struct genl_ops *ops;
     567             :         int hdrlen;
     568             : };
     569             : 
     570           0 : static int genl_start(struct netlink_callback *cb)
     571             : {
     572           0 :         struct genl_start_context *ctx = cb->data;
     573           0 :         const struct genl_ops *ops = ctx->ops;
     574           0 :         struct genl_dumpit_info *info;
     575           0 :         struct nlattr **attrs = NULL;
     576           0 :         int rc = 0;
     577             : 
     578           0 :         if (ops->validate & GENL_DONT_VALIDATE_DUMP)
     579           0 :                 goto no_attrs;
     580             : 
     581           0 :         if (ctx->nlh->nlmsg_len < nlmsg_msg_size(ctx->hdrlen))
     582             :                 return -EINVAL;
     583             : 
     584           0 :         attrs = genl_family_rcv_msg_attrs_parse(ctx->family, ctx->nlh, ctx->extack,
     585             :                                                 ops, ctx->hdrlen,
     586             :                                                 GENL_DONT_VALIDATE_DUMP_STRICT);
     587           0 :         if (IS_ERR(attrs))
     588           0 :                 return PTR_ERR(attrs);
     589             : 
     590           0 : no_attrs:
     591           0 :         info = genl_dumpit_info_alloc();
     592           0 :         if (!info) {
     593           0 :                 genl_family_rcv_msg_attrs_free(attrs);
     594           0 :                 return -ENOMEM;
     595             :         }
     596           0 :         info->family = ctx->family;
     597           0 :         info->op = *ops;
     598           0 :         info->attrs = attrs;
     599             : 
     600           0 :         cb->data = info;
     601           0 :         if (ops->start) {
     602           0 :                 if (!ctx->family->parallel_ops)
     603           0 :                         genl_lock();
     604           0 :                 rc = ops->start(cb);
     605           0 :                 if (!ctx->family->parallel_ops)
     606           0 :                         genl_unlock();
     607             :         }
     608             : 
     609           0 :         if (rc) {
     610           0 :                 genl_family_rcv_msg_attrs_free(info->attrs);
     611           0 :                 genl_dumpit_info_free(info);
     612           0 :                 cb->data = NULL;
     613             :         }
     614             :         return rc;
     615             : }
     616             : 
     617           0 : static int genl_lock_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
     618             : {
     619           0 :         const struct genl_ops *ops = &genl_dumpit_info(cb)->op;
     620           0 :         int rc;
     621             : 
     622           0 :         genl_lock();
     623           0 :         rc = ops->dumpit(skb, cb);
     624           0 :         genl_unlock();
     625           0 :         return rc;
     626             : }
     627             : 
     628           0 : static int genl_lock_done(struct netlink_callback *cb)
     629             : {
     630           0 :         const struct genl_dumpit_info *info = genl_dumpit_info(cb);
     631           0 :         const struct genl_ops *ops = &info->op;
     632           0 :         int rc = 0;
     633             : 
     634           0 :         if (ops->done) {
     635           0 :                 genl_lock();
     636           0 :                 rc = ops->done(cb);
     637           0 :                 genl_unlock();
     638             :         }
     639           0 :         genl_family_rcv_msg_attrs_free(info->attrs);
     640           0 :         genl_dumpit_info_free(info);
     641           0 :         return rc;
     642             : }
     643             : 
     644           0 : static int genl_parallel_done(struct netlink_callback *cb)
     645             : {
     646           0 :         const struct genl_dumpit_info *info = genl_dumpit_info(cb);
     647           0 :         const struct genl_ops *ops = &info->op;
     648           0 :         int rc = 0;
     649             : 
     650           0 :         if (ops->done)
     651           0 :                 rc = ops->done(cb);
     652           0 :         genl_family_rcv_msg_attrs_free(info->attrs);
     653           0 :         genl_dumpit_info_free(info);
     654           0 :         return rc;
     655             : }
     656             : 
     657           0 : static int genl_family_rcv_msg_dumpit(const struct genl_family *family,
     658             :                                       struct sk_buff *skb,
     659             :                                       struct nlmsghdr *nlh,
     660             :                                       struct netlink_ext_ack *extack,
     661             :                                       const struct genl_ops *ops,
     662             :                                       int hdrlen, struct net *net)
     663             : {
     664           0 :         struct genl_start_context ctx;
     665           0 :         int err;
     666             : 
     667           0 :         if (!ops->dumpit)
     668             :                 return -EOPNOTSUPP;
     669             : 
     670           0 :         ctx.family = family;
     671           0 :         ctx.nlh = nlh;
     672           0 :         ctx.extack = extack;
     673           0 :         ctx.ops = ops;
     674           0 :         ctx.hdrlen = hdrlen;
     675             : 
     676           0 :         if (!family->parallel_ops) {
     677           0 :                 struct netlink_dump_control c = {
     678           0 :                         .module = family->module,
     679             :                         .data = &ctx,
     680             :                         .start = genl_start,
     681             :                         .dump = genl_lock_dumpit,
     682             :                         .done = genl_lock_done,
     683             :                 };
     684             : 
     685           0 :                 genl_unlock();
     686           0 :                 err = __netlink_dump_start(net->genl_sock, skb, nlh, &c);
     687           0 :                 genl_lock();
     688             :         } else {
     689           0 :                 struct netlink_dump_control c = {
     690           0 :                         .module = family->module,
     691             :                         .data = &ctx,
     692             :                         .start = genl_start,
     693             :                         .dump = ops->dumpit,
     694             :                         .done = genl_parallel_done,
     695             :                 };
     696             : 
     697           0 :                 err = __netlink_dump_start(net->genl_sock, skb, nlh, &c);
     698             :         }
     699             : 
     700             :         return err;
     701             : }
     702             : 
     703           0 : static int genl_family_rcv_msg_doit(const struct genl_family *family,
     704             :                                     struct sk_buff *skb,
     705             :                                     struct nlmsghdr *nlh,
     706             :                                     struct netlink_ext_ack *extack,
     707             :                                     const struct genl_ops *ops,
     708             :                                     int hdrlen, struct net *net)
     709             : {
     710           0 :         struct nlattr **attrbuf;
     711           0 :         struct genl_info info;
     712           0 :         int err;
     713             : 
     714           0 :         if (!ops->doit)
     715             :                 return -EOPNOTSUPP;
     716             : 
     717           0 :         attrbuf = genl_family_rcv_msg_attrs_parse(family, nlh, extack,
     718             :                                                   ops, hdrlen,
     719             :                                                   GENL_DONT_VALIDATE_STRICT);
     720           0 :         if (IS_ERR(attrbuf))
     721           0 :                 return PTR_ERR(attrbuf);
     722             : 
     723           0 :         info.snd_seq = nlh->nlmsg_seq;
     724           0 :         info.snd_portid = NETLINK_CB(skb).portid;
     725           0 :         info.nlhdr = nlh;
     726           0 :         info.genlhdr = nlmsg_data(nlh);
     727           0 :         info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN;
     728           0 :         info.attrs = attrbuf;
     729           0 :         info.extack = extack;
     730           0 :         genl_info_net_set(&info, net);
     731           0 :         memset(&info.user_ptr, 0, sizeof(info.user_ptr));
     732             : 
     733           0 :         if (family->pre_doit) {
     734           0 :                 err = family->pre_doit(ops, skb, &info);
     735           0 :                 if (err)
     736           0 :                         goto out;
     737             :         }
     738             : 
     739           0 :         err = ops->doit(skb, &info);
     740             : 
     741           0 :         if (family->post_doit)
     742           0 :                 family->post_doit(ops, skb, &info);
     743             : 
     744           0 : out:
     745           0 :         genl_family_rcv_msg_attrs_free(attrbuf);
     746             : 
     747           0 :         return err;
     748             : }
     749             : 
     750           0 : static int genl_family_rcv_msg(const struct genl_family *family,
     751             :                                struct sk_buff *skb,
     752             :                                struct nlmsghdr *nlh,
     753             :                                struct netlink_ext_ack *extack)
     754             : {
     755           0 :         struct net *net = sock_net(skb->sk);
     756           0 :         struct genlmsghdr *hdr = nlmsg_data(nlh);
     757           0 :         struct genl_ops op;
     758           0 :         int hdrlen;
     759             : 
     760             :         /* this family doesn't exist in this netns */
     761           0 :         if (!family->netnsok && !net_eq(net, &init_net))
     762             :                 return -ENOENT;
     763             : 
     764           0 :         hdrlen = GENL_HDRLEN + family->hdrsize;
     765           0 :         if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
     766             :                 return -EINVAL;
     767             : 
     768           0 :         if (genl_get_cmd(hdr->cmd, family, &op))
     769             :                 return -EOPNOTSUPP;
     770             : 
     771           0 :         if ((op.flags & GENL_ADMIN_PERM) &&
     772           0 :             !netlink_capable(skb, CAP_NET_ADMIN))
     773             :                 return -EPERM;
     774             : 
     775           0 :         if ((op.flags & GENL_UNS_ADMIN_PERM) &&
     776           0 :             !netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN))
     777             :                 return -EPERM;
     778             : 
     779           0 :         if ((nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP)
     780           0 :                 return genl_family_rcv_msg_dumpit(family, skb, nlh, extack,
     781             :                                                   &op, hdrlen, net);
     782             :         else
     783           0 :                 return genl_family_rcv_msg_doit(family, skb, nlh, extack,
     784             :                                                 &op, hdrlen, net);
     785             : }
     786             : 
     787           0 : static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
     788             :                         struct netlink_ext_ack *extack)
     789             : {
     790           0 :         const struct genl_family *family;
     791           0 :         int err;
     792             : 
     793           0 :         family = genl_family_find_byid(nlh->nlmsg_type);
     794           0 :         if (family == NULL)
     795             :                 return -ENOENT;
     796             : 
     797           0 :         if (!family->parallel_ops)
     798           0 :                 genl_lock();
     799             : 
     800           0 :         err = genl_family_rcv_msg(family, skb, nlh, extack);
     801             : 
     802           0 :         if (!family->parallel_ops)
     803           0 :                 genl_unlock();
     804             : 
     805             :         return err;
     806             : }
     807             : 
     808           0 : static void genl_rcv(struct sk_buff *skb)
     809             : {
     810           0 :         down_read(&cb_lock);
     811           0 :         netlink_rcv_skb(skb, &genl_rcv_msg);
     812           0 :         up_read(&cb_lock);
     813           0 : }
     814             : 
     815             : /**************************************************************************
     816             :  * Controller
     817             :  **************************************************************************/
     818             : 
     819             : static struct genl_family genl_ctrl;
     820             : 
     821           2 : static int ctrl_fill_info(const struct genl_family *family, u32 portid, u32 seq,
     822             :                           u32 flags, struct sk_buff *skb, u8 cmd)
     823             : {
     824           2 :         void *hdr;
     825             : 
     826           2 :         hdr = genlmsg_put(skb, portid, seq, &genl_ctrl, flags, cmd);
     827           2 :         if (hdr == NULL)
     828             :                 return -1;
     829             : 
     830           2 :         if (nla_put_string(skb, CTRL_ATTR_FAMILY_NAME, family->name) ||
     831           2 :             nla_put_u16(skb, CTRL_ATTR_FAMILY_ID, family->id) ||
     832           2 :             nla_put_u32(skb, CTRL_ATTR_VERSION, family->version) ||
     833           2 :             nla_put_u32(skb, CTRL_ATTR_HDRSIZE, family->hdrsize) ||
     834           2 :             nla_put_u32(skb, CTRL_ATTR_MAXATTR, family->maxattr))
     835           0 :                 goto nla_put_failure;
     836             : 
     837           2 :         if (genl_get_cmd_cnt(family)) {
     838           2 :                 struct nlattr *nla_ops;
     839           2 :                 int i;
     840             : 
     841           2 :                 nla_ops = nla_nest_start_noflag(skb, CTRL_ATTR_OPS);
     842           2 :                 if (nla_ops == NULL)
     843           0 :                         goto nla_put_failure;
     844             : 
     845           6 :                 for (i = 0; i < genl_get_cmd_cnt(family); i++) {
     846           4 :                         struct nlattr *nest;
     847           4 :                         struct genl_ops op;
     848           4 :                         u32 op_flags;
     849             : 
     850           4 :                         genl_get_cmd_by_index(i, family, &op);
     851           4 :                         op_flags = op.flags;
     852           4 :                         if (op.dumpit)
     853           1 :                                 op_flags |= GENL_CMD_CAP_DUMP;
     854           4 :                         if (op.doit)
     855           4 :                                 op_flags |= GENL_CMD_CAP_DO;
     856           4 :                         if (op.policy)
     857           4 :                                 op_flags |= GENL_CMD_CAP_HASPOL;
     858             : 
     859           4 :                         nest = nla_nest_start_noflag(skb, i + 1);
     860           4 :                         if (nest == NULL)
     861           0 :                                 goto nla_put_failure;
     862             : 
     863           4 :                         if (nla_put_u32(skb, CTRL_ATTR_OP_ID, op.cmd) ||
     864           4 :                             nla_put_u32(skb, CTRL_ATTR_OP_FLAGS, op_flags))
     865           0 :                                 goto nla_put_failure;
     866             : 
     867           4 :                         nla_nest_end(skb, nest);
     868             :                 }
     869             : 
     870           2 :                 nla_nest_end(skb, nla_ops);
     871             :         }
     872             : 
     873           2 :         if (family->n_mcgrps) {
     874           0 :                 struct nlattr *nla_grps;
     875           0 :                 int i;
     876             : 
     877           0 :                 nla_grps = nla_nest_start_noflag(skb, CTRL_ATTR_MCAST_GROUPS);
     878           0 :                 if (nla_grps == NULL)
     879           0 :                         goto nla_put_failure;
     880             : 
     881           0 :                 for (i = 0; i < family->n_mcgrps; i++) {
     882           0 :                         struct nlattr *nest;
     883           0 :                         const struct genl_multicast_group *grp;
     884             : 
     885           0 :                         grp = &family->mcgrps[i];
     886             : 
     887           0 :                         nest = nla_nest_start_noflag(skb, i + 1);
     888           0 :                         if (nest == NULL)
     889           0 :                                 goto nla_put_failure;
     890             : 
     891           0 :                         if (nla_put_u32(skb, CTRL_ATTR_MCAST_GRP_ID,
     892           0 :                                         family->mcgrp_offset + i) ||
     893           0 :                             nla_put_string(skb, CTRL_ATTR_MCAST_GRP_NAME,
     894           0 :                                            grp->name))
     895           0 :                                 goto nla_put_failure;
     896             : 
     897           0 :                         nla_nest_end(skb, nest);
     898             :                 }
     899           0 :                 nla_nest_end(skb, nla_grps);
     900             :         }
     901             : 
     902           2 :         genlmsg_end(skb, hdr);
     903           2 :         return 0;
     904             : 
     905           0 : nla_put_failure:
     906           0 :         genlmsg_cancel(skb, hdr);
     907           0 :         return -EMSGSIZE;
     908             : }
     909             : 
     910           0 : static int ctrl_fill_mcgrp_info(const struct genl_family *family,
     911             :                                 const struct genl_multicast_group *grp,
     912             :                                 int grp_id, u32 portid, u32 seq, u32 flags,
     913             :                                 struct sk_buff *skb, u8 cmd)
     914             : {
     915           0 :         void *hdr;
     916           0 :         struct nlattr *nla_grps;
     917           0 :         struct nlattr *nest;
     918             : 
     919           0 :         hdr = genlmsg_put(skb, portid, seq, &genl_ctrl, flags, cmd);
     920           0 :         if (hdr == NULL)
     921             :                 return -1;
     922             : 
     923           0 :         if (nla_put_string(skb, CTRL_ATTR_FAMILY_NAME, family->name) ||
     924           0 :             nla_put_u16(skb, CTRL_ATTR_FAMILY_ID, family->id))
     925           0 :                 goto nla_put_failure;
     926             : 
     927           0 :         nla_grps = nla_nest_start_noflag(skb, CTRL_ATTR_MCAST_GROUPS);
     928           0 :         if (nla_grps == NULL)
     929           0 :                 goto nla_put_failure;
     930             : 
     931           0 :         nest = nla_nest_start_noflag(skb, 1);
     932           0 :         if (nest == NULL)
     933           0 :                 goto nla_put_failure;
     934             : 
     935           0 :         if (nla_put_u32(skb, CTRL_ATTR_MCAST_GRP_ID, grp_id) ||
     936           0 :             nla_put_string(skb, CTRL_ATTR_MCAST_GRP_NAME,
     937           0 :                            grp->name))
     938           0 :                 goto nla_put_failure;
     939             : 
     940           0 :         nla_nest_end(skb, nest);
     941           0 :         nla_nest_end(skb, nla_grps);
     942             : 
     943           0 :         genlmsg_end(skb, hdr);
     944           0 :         return 0;
     945             : 
     946           0 : nla_put_failure:
     947           0 :         genlmsg_cancel(skb, hdr);
     948           0 :         return -EMSGSIZE;
     949             : }
     950             : 
     951           0 : static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb)
     952             : {
     953           0 :         int n = 0;
     954           0 :         struct genl_family *rt;
     955           0 :         struct net *net = sock_net(skb->sk);
     956           0 :         int fams_to_skip = cb->args[0];
     957           0 :         unsigned int id;
     958             : 
     959           0 :         idr_for_each_entry(&genl_fam_idr, rt, id) {
     960           0 :                 if (!rt->netnsok && !net_eq(net, &init_net))
     961             :                         continue;
     962             : 
     963           0 :                 if (n++ < fams_to_skip)
     964           0 :                         continue;
     965             : 
     966           0 :                 if (ctrl_fill_info(rt, NETLINK_CB(cb->skb).portid,
     967           0 :                                    cb->nlh->nlmsg_seq, NLM_F_MULTI,
     968             :                                    skb, CTRL_CMD_NEWFAMILY) < 0) {
     969             :                         n--;
     970             :                         break;
     971             :                 }
     972             :         }
     973             : 
     974           0 :         cb->args[0] = n;
     975           0 :         return skb->len;
     976             : }
     977             : 
     978           2 : static struct sk_buff *ctrl_build_family_msg(const struct genl_family *family,
     979             :                                              u32 portid, int seq, u8 cmd)
     980             : {
     981           2 :         struct sk_buff *skb;
     982           2 :         int err;
     983             : 
     984           2 :         skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
     985           2 :         if (skb == NULL)
     986           2 :                 return ERR_PTR(-ENOBUFS);
     987             : 
     988           2 :         err = ctrl_fill_info(family, portid, seq, 0, skb, cmd);
     989           2 :         if (err < 0) {
     990           0 :                 nlmsg_free(skb);
     991           0 :                 return ERR_PTR(err);
     992             :         }
     993             : 
     994             :         return skb;
     995             : }
     996             : 
     997             : static struct sk_buff *
     998           0 : ctrl_build_mcgrp_msg(const struct genl_family *family,
     999             :                      const struct genl_multicast_group *grp,
    1000             :                      int grp_id, u32 portid, int seq, u8 cmd)
    1001             : {
    1002           0 :         struct sk_buff *skb;
    1003           0 :         int err;
    1004             : 
    1005           0 :         skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
    1006           0 :         if (skb == NULL)
    1007           0 :                 return ERR_PTR(-ENOBUFS);
    1008             : 
    1009           0 :         err = ctrl_fill_mcgrp_info(family, grp, grp_id, portid,
    1010             :                                    seq, 0, skb, cmd);
    1011           0 :         if (err < 0) {
    1012           0 :                 nlmsg_free(skb);
    1013           0 :                 return ERR_PTR(err);
    1014             :         }
    1015             : 
    1016             :         return skb;
    1017             : }
    1018             : 
    1019             : static const struct nla_policy ctrl_policy_family[] = {
    1020             :         [CTRL_ATTR_FAMILY_ID]   = { .type = NLA_U16 },
    1021             :         [CTRL_ATTR_FAMILY_NAME] = { .type = NLA_NUL_STRING,
    1022             :                                     .len = GENL_NAMSIZ - 1 },
    1023             : };
    1024             : 
    1025           0 : static int ctrl_getfamily(struct sk_buff *skb, struct genl_info *info)
    1026             : {
    1027           0 :         struct sk_buff *msg;
    1028           0 :         const struct genl_family *res = NULL;
    1029           0 :         int err = -EINVAL;
    1030             : 
    1031           0 :         if (info->attrs[CTRL_ATTR_FAMILY_ID]) {
    1032           0 :                 u16 id = nla_get_u16(info->attrs[CTRL_ATTR_FAMILY_ID]);
    1033           0 :                 res = genl_family_find_byid(id);
    1034           0 :                 err = -ENOENT;
    1035             :         }
    1036             : 
    1037           0 :         if (info->attrs[CTRL_ATTR_FAMILY_NAME]) {
    1038           0 :                 char *name;
    1039             : 
    1040           0 :                 name = nla_data(info->attrs[CTRL_ATTR_FAMILY_NAME]);
    1041           0 :                 res = genl_family_find_byname(name);
    1042             : #ifdef CONFIG_MODULES
    1043             :                 if (res == NULL) {
    1044             :                         genl_unlock();
    1045             :                         up_read(&cb_lock);
    1046             :                         request_module("net-pf-%d-proto-%d-family-%s",
    1047             :                                        PF_NETLINK, NETLINK_GENERIC, name);
    1048             :                         down_read(&cb_lock);
    1049             :                         genl_lock();
    1050             :                         res = genl_family_find_byname(name);
    1051             :                 }
    1052             : #endif
    1053           0 :                 err = -ENOENT;
    1054             :         }
    1055             : 
    1056           0 :         if (res == NULL)
    1057             :                 return err;
    1058             : 
    1059           0 :         if (!res->netnsok && !net_eq(genl_info_net(info), &init_net)) {
    1060             :                 /* family doesn't exist here */
    1061             :                 return -ENOENT;
    1062             :         }
    1063             : 
    1064           0 :         msg = ctrl_build_family_msg(res, info->snd_portid, info->snd_seq,
    1065             :                                     CTRL_CMD_NEWFAMILY);
    1066           0 :         if (IS_ERR(msg))
    1067           0 :                 return PTR_ERR(msg);
    1068             : 
    1069           0 :         return genlmsg_reply(msg, info);
    1070             : }
    1071             : 
    1072           4 : static int genl_ctrl_event(int event, const struct genl_family *family,
    1073             :                            const struct genl_multicast_group *grp,
    1074             :                            int grp_id)
    1075             : {
    1076           4 :         struct sk_buff *msg;
    1077             : 
    1078             :         /* genl is still initialising */
    1079           4 :         if (!init_net.genl_sock)
    1080             :                 return 0;
    1081             : 
    1082           2 :         switch (event) {
    1083           2 :         case CTRL_CMD_NEWFAMILY:
    1084             :         case CTRL_CMD_DELFAMILY:
    1085           2 :                 WARN_ON(grp);
    1086           2 :                 msg = ctrl_build_family_msg(family, 0, 0, event);
    1087           2 :                 break;
    1088           0 :         case CTRL_CMD_NEWMCAST_GRP:
    1089             :         case CTRL_CMD_DELMCAST_GRP:
    1090           0 :                 BUG_ON(!grp);
    1091           0 :                 msg = ctrl_build_mcgrp_msg(family, grp, grp_id, 0, 0, event);
    1092           0 :                 break;
    1093             :         default:
    1094             :                 return -EINVAL;
    1095             :         }
    1096             : 
    1097           2 :         if (IS_ERR(msg))
    1098           0 :                 return PTR_ERR(msg);
    1099             : 
    1100           2 :         if (!family->netnsok) {
    1101           1 :                 genlmsg_multicast_netns(&genl_ctrl, &init_net, msg, 0,
    1102             :                                         0, GFP_KERNEL);
    1103             :         } else {
    1104           1 :                 rcu_read_lock();
    1105           1 :                 genlmsg_multicast_allns(&genl_ctrl, msg, 0,
    1106             :                                         0, GFP_ATOMIC);
    1107           1 :                 rcu_read_unlock();
    1108             :         }
    1109             : 
    1110             :         return 0;
    1111             : }
    1112             : 
    1113             : struct ctrl_dump_policy_ctx {
    1114             :         struct netlink_policy_dump_state *state;
    1115             :         const struct genl_family *rt;
    1116             :         unsigned int opidx;
    1117             :         u32 op;
    1118             :         u16 fam_id;
    1119             :         u8 policies:1,
    1120             :            single_op:1;
    1121             : };
    1122             : 
    1123             : static const struct nla_policy ctrl_policy_policy[] = {
    1124             :         [CTRL_ATTR_FAMILY_ID]   = { .type = NLA_U16 },
    1125             :         [CTRL_ATTR_FAMILY_NAME] = { .type = NLA_NUL_STRING,
    1126             :                                     .len = GENL_NAMSIZ - 1 },
    1127             :         [CTRL_ATTR_OP]          = { .type = NLA_U32 },
    1128             : };
    1129             : 
    1130           0 : static int ctrl_dumppolicy_start(struct netlink_callback *cb)
    1131             : {
    1132           0 :         const struct genl_dumpit_info *info = genl_dumpit_info(cb);
    1133           0 :         struct ctrl_dump_policy_ctx *ctx = (void *)cb->ctx;
    1134           0 :         struct nlattr **tb = info->attrs;
    1135           0 :         const struct genl_family *rt;
    1136           0 :         struct genl_ops op;
    1137           0 :         int err, i;
    1138             : 
    1139           0 :         BUILD_BUG_ON(sizeof(*ctx) > sizeof(cb->ctx));
    1140             : 
    1141           0 :         if (!tb[CTRL_ATTR_FAMILY_ID] && !tb[CTRL_ATTR_FAMILY_NAME])
    1142             :                 return -EINVAL;
    1143             : 
    1144           0 :         if (tb[CTRL_ATTR_FAMILY_ID]) {
    1145           0 :                 ctx->fam_id = nla_get_u16(tb[CTRL_ATTR_FAMILY_ID]);
    1146             :         } else {
    1147           0 :                 rt = genl_family_find_byname(
    1148           0 :                         nla_data(tb[CTRL_ATTR_FAMILY_NAME]));
    1149           0 :                 if (!rt)
    1150             :                         return -ENOENT;
    1151           0 :                 ctx->fam_id = rt->id;
    1152             :         }
    1153             : 
    1154           0 :         rt = genl_family_find_byid(ctx->fam_id);
    1155           0 :         if (!rt)
    1156             :                 return -ENOENT;
    1157             : 
    1158           0 :         ctx->rt = rt;
    1159             : 
    1160           0 :         if (tb[CTRL_ATTR_OP]) {
    1161           0 :                 ctx->single_op = true;
    1162           0 :                 ctx->op = nla_get_u32(tb[CTRL_ATTR_OP]);
    1163             : 
    1164           0 :                 err = genl_get_cmd(ctx->op, rt, &op);
    1165           0 :                 if (err) {
    1166           0 :                         NL_SET_BAD_ATTR(cb->extack, tb[CTRL_ATTR_OP]);
    1167           0 :                         return err;
    1168             :                 }
    1169             : 
    1170           0 :                 if (!op.policy)
    1171             :                         return -ENODATA;
    1172             : 
    1173           0 :                 return netlink_policy_dump_add_policy(&ctx->state, op.policy,
    1174             :                                                       op.maxattr);
    1175             :         }
    1176             : 
    1177           0 :         for (i = 0; i < genl_get_cmd_cnt(rt); i++) {
    1178           0 :                 genl_get_cmd_by_index(i, rt, &op);
    1179             : 
    1180           0 :                 if (op.policy) {
    1181           0 :                         err = netlink_policy_dump_add_policy(&ctx->state,
    1182             :                                                              op.policy,
    1183             :                                                              op.maxattr);
    1184           0 :                         if (err)
    1185           0 :                                 return err;
    1186             :                 }
    1187             :         }
    1188             : 
    1189           0 :         if (!ctx->state)
    1190           0 :                 return -ENODATA;
    1191             :         return 0;
    1192             : }
    1193             : 
    1194           0 : static void *ctrl_dumppolicy_prep(struct sk_buff *skb,
    1195             :                                   struct netlink_callback *cb)
    1196             : {
    1197           0 :         struct ctrl_dump_policy_ctx *ctx = (void *)cb->ctx;
    1198           0 :         void *hdr;
    1199             : 
    1200           0 :         hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
    1201           0 :                           cb->nlh->nlmsg_seq, &genl_ctrl,
    1202             :                           NLM_F_MULTI, CTRL_CMD_GETPOLICY);
    1203           0 :         if (!hdr)
    1204             :                 return NULL;
    1205             : 
    1206           0 :         if (nla_put_u16(skb, CTRL_ATTR_FAMILY_ID, ctx->fam_id))
    1207           0 :                 return NULL;
    1208             : 
    1209             :         return hdr;
    1210             : }
    1211             : 
    1212           0 : static int ctrl_dumppolicy_put_op(struct sk_buff *skb,
    1213             :                                   struct netlink_callback *cb,
    1214             :                                   struct genl_ops *op)
    1215             : {
    1216           0 :         struct ctrl_dump_policy_ctx *ctx = (void *)cb->ctx;
    1217           0 :         struct nlattr *nest_pol, *nest_op;
    1218           0 :         void *hdr;
    1219           0 :         int idx;
    1220             : 
    1221             :         /* skip if we have nothing to show */
    1222           0 :         if (!op->policy)
    1223             :                 return 0;
    1224           0 :         if (!op->doit &&
    1225           0 :             (!op->dumpit || op->validate & GENL_DONT_VALIDATE_DUMP))
    1226             :                 return 0;
    1227             : 
    1228           0 :         hdr = ctrl_dumppolicy_prep(skb, cb);
    1229           0 :         if (!hdr)
    1230             :                 return -ENOBUFS;
    1231             : 
    1232           0 :         nest_pol = nla_nest_start(skb, CTRL_ATTR_OP_POLICY);
    1233           0 :         if (!nest_pol)
    1234           0 :                 goto err;
    1235             : 
    1236           0 :         nest_op = nla_nest_start(skb, op->cmd);
    1237           0 :         if (!nest_op)
    1238           0 :                 goto err;
    1239             : 
    1240             :         /* for now both do/dump are always the same */
    1241           0 :         idx = netlink_policy_dump_get_policy_idx(ctx->state,
    1242             :                                                  op->policy,
    1243             :                                                  op->maxattr);
    1244             : 
    1245           0 :         if (op->doit && nla_put_u32(skb, CTRL_ATTR_POLICY_DO, idx))
    1246           0 :                 goto err;
    1247             : 
    1248           0 :         if (op->dumpit && !(op->validate & GENL_DONT_VALIDATE_DUMP) &&
    1249           0 :             nla_put_u32(skb, CTRL_ATTR_POLICY_DUMP, idx))
    1250           0 :                 goto err;
    1251             : 
    1252           0 :         nla_nest_end(skb, nest_op);
    1253           0 :         nla_nest_end(skb, nest_pol);
    1254           0 :         genlmsg_end(skb, hdr);
    1255             : 
    1256           0 :         return 0;
    1257           0 : err:
    1258           0 :         genlmsg_cancel(skb, hdr);
    1259           0 :         return -ENOBUFS;
    1260             : }
    1261             : 
    1262           0 : static int ctrl_dumppolicy(struct sk_buff *skb, struct netlink_callback *cb)
    1263             : {
    1264           0 :         struct ctrl_dump_policy_ctx *ctx = (void *)cb->ctx;
    1265           0 :         void *hdr;
    1266             : 
    1267           0 :         if (!ctx->policies) {
    1268           0 :                 while (ctx->opidx < genl_get_cmd_cnt(ctx->rt)) {
    1269           0 :                         struct genl_ops op;
    1270             : 
    1271           0 :                         if (ctx->single_op) {
    1272           0 :                                 int err;
    1273             : 
    1274           0 :                                 err = genl_get_cmd(ctx->op, ctx->rt, &op);
    1275           0 :                                 if (WARN_ON(err))
    1276           0 :                                         return skb->len;
    1277             : 
    1278             :                                 /* break out of the loop after this one */
    1279           0 :                                 ctx->opidx = genl_get_cmd_cnt(ctx->rt);
    1280             :                         } else {
    1281           0 :                                 genl_get_cmd_by_index(ctx->opidx, ctx->rt, &op);
    1282             :                         }
    1283             : 
    1284           0 :                         if (ctrl_dumppolicy_put_op(skb, cb, &op))
    1285           0 :                                 return skb->len;
    1286             : 
    1287           0 :                         ctx->opidx++;
    1288             :                 }
    1289             : 
    1290             :                 /* completed with the per-op policy index list */
    1291           0 :                 ctx->policies = true;
    1292             :         }
    1293             : 
    1294           0 :         while (netlink_policy_dump_loop(ctx->state)) {
    1295           0 :                 struct nlattr *nest;
    1296             : 
    1297           0 :                 hdr = ctrl_dumppolicy_prep(skb, cb);
    1298           0 :                 if (!hdr)
    1299           0 :                         goto nla_put_failure;
    1300             : 
    1301           0 :                 nest = nla_nest_start(skb, CTRL_ATTR_POLICY);
    1302           0 :                 if (!nest)
    1303           0 :                         goto nla_put_failure;
    1304             : 
    1305           0 :                 if (netlink_policy_dump_write(skb, ctx->state))
    1306           0 :                         goto nla_put_failure;
    1307             : 
    1308           0 :                 nla_nest_end(skb, nest);
    1309             : 
    1310           0 :                 genlmsg_end(skb, hdr);
    1311             :         }
    1312             : 
    1313           0 :         return skb->len;
    1314             : 
    1315           0 : nla_put_failure:
    1316           0 :         genlmsg_cancel(skb, hdr);
    1317           0 :         return skb->len;
    1318             : }
    1319             : 
    1320           0 : static int ctrl_dumppolicy_done(struct netlink_callback *cb)
    1321             : {
    1322           0 :         struct ctrl_dump_policy_ctx *ctx = (void *)cb->ctx;
    1323             : 
    1324           0 :         netlink_policy_dump_free(ctx->state);
    1325           0 :         return 0;
    1326             : }
    1327             : 
    1328             : static const struct genl_ops genl_ctrl_ops[] = {
    1329             :         {
    1330             :                 .cmd            = CTRL_CMD_GETFAMILY,
    1331             :                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
    1332             :                 .policy         = ctrl_policy_family,
    1333             :                 .maxattr        = ARRAY_SIZE(ctrl_policy_family) - 1,
    1334             :                 .doit           = ctrl_getfamily,
    1335             :                 .dumpit         = ctrl_dumpfamily,
    1336             :         },
    1337             :         {
    1338             :                 .cmd            = CTRL_CMD_GETPOLICY,
    1339             :                 .policy         = ctrl_policy_policy,
    1340             :                 .maxattr        = ARRAY_SIZE(ctrl_policy_policy) - 1,
    1341             :                 .start          = ctrl_dumppolicy_start,
    1342             :                 .dumpit         = ctrl_dumppolicy,
    1343             :                 .done           = ctrl_dumppolicy_done,
    1344             :         },
    1345             : };
    1346             : 
    1347             : static const struct genl_multicast_group genl_ctrl_groups[] = {
    1348             :         { .name = "notify", },
    1349             : };
    1350             : 
    1351             : static struct genl_family genl_ctrl __ro_after_init = {
    1352             :         .module = THIS_MODULE,
    1353             :         .ops = genl_ctrl_ops,
    1354             :         .n_ops = ARRAY_SIZE(genl_ctrl_ops),
    1355             :         .mcgrps = genl_ctrl_groups,
    1356             :         .n_mcgrps = ARRAY_SIZE(genl_ctrl_groups),
    1357             :         .id = GENL_ID_CTRL,
    1358             :         .name = "nlctrl",
    1359             :         .version = 0x2,
    1360             :         .netnsok = true,
    1361             : };
    1362             : 
    1363           0 : static int genl_bind(struct net *net, int group)
    1364             : {
    1365           0 :         const struct genl_family *family;
    1366           0 :         unsigned int id;
    1367           0 :         int ret = 0;
    1368             : 
    1369           0 :         genl_lock_all();
    1370             : 
    1371           0 :         idr_for_each_entry(&genl_fam_idr, family, id) {
    1372           0 :                 const struct genl_multicast_group *grp;
    1373           0 :                 int i;
    1374             : 
    1375           0 :                 if (family->n_mcgrps == 0)
    1376           0 :                         continue;
    1377             : 
    1378           0 :                 i = group - family->mcgrp_offset;
    1379           0 :                 if (i < 0 || i >= family->n_mcgrps)
    1380           0 :                         continue;
    1381             : 
    1382           0 :                 grp = &family->mcgrps[i];
    1383           0 :                 if ((grp->flags & GENL_UNS_ADMIN_PERM) &&
    1384           0 :                     !ns_capable(net->user_ns, CAP_NET_ADMIN))
    1385           0 :                         ret = -EPERM;
    1386             : 
    1387             :                 break;
    1388             :         }
    1389             : 
    1390           0 :         genl_unlock_all();
    1391           0 :         return ret;
    1392             : }
    1393             : 
    1394           1 : static int __net_init genl_pernet_init(struct net *net)
    1395             : {
    1396           1 :         struct netlink_kernel_cfg cfg = {
    1397             :                 .input          = genl_rcv,
    1398             :                 .flags          = NL_CFG_F_NONROOT_RECV,
    1399             :                 .bind           = genl_bind,
    1400             :         };
    1401             : 
    1402             :         /* we'll bump the group number right afterwards */
    1403           1 :         net->genl_sock = netlink_kernel_create(net, NETLINK_GENERIC, &cfg);
    1404             : 
    1405           1 :         if (!net->genl_sock && net_eq(net, &init_net))
    1406           0 :                 panic("GENL: Cannot initialize generic netlink\n");
    1407             : 
    1408           1 :         if (!net->genl_sock)
    1409             :                 return -ENOMEM;
    1410             : 
    1411             :         return 0;
    1412             : }
    1413             : 
    1414           0 : static void __net_exit genl_pernet_exit(struct net *net)
    1415             : {
    1416           0 :         netlink_kernel_release(net->genl_sock);
    1417           0 :         net->genl_sock = NULL;
    1418           0 : }
    1419             : 
    1420             : static struct pernet_operations genl_pernet_ops = {
    1421             :         .init = genl_pernet_init,
    1422             :         .exit = genl_pernet_exit,
    1423             : };
    1424             : 
    1425           1 : static int __init genl_init(void)
    1426             : {
    1427           1 :         int err;
    1428             : 
    1429           1 :         err = genl_register_family(&genl_ctrl);
    1430           1 :         if (err < 0)
    1431           0 :                 goto problem;
    1432             : 
    1433           1 :         err = register_pernet_subsys(&genl_pernet_ops);
    1434           1 :         if (err)
    1435           0 :                 goto problem;
    1436             : 
    1437           1 :         return 0;
    1438             : 
    1439           0 : problem:
    1440           0 :         panic("GENL: Cannot register controller: %d\n", err);
    1441             : }
    1442             : 
    1443             : core_initcall(genl_init);
    1444             : 
    1445           1 : static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group,
    1446             :                          gfp_t flags)
    1447             : {
    1448           1 :         struct sk_buff *tmp;
    1449           1 :         struct net *net, *prev = NULL;
    1450           1 :         bool delivered = false;
    1451           1 :         int err;
    1452             : 
    1453           2 :         for_each_net_rcu(net) {
    1454           1 :                 if (prev) {
    1455           0 :                         tmp = skb_clone(skb, flags);
    1456           0 :                         if (!tmp) {
    1457           0 :                                 err = -ENOMEM;
    1458           0 :                                 goto error;
    1459             :                         }
    1460           0 :                         err = nlmsg_multicast(prev->genl_sock, tmp,
    1461             :                                               portid, group, flags);
    1462           0 :                         if (!err)
    1463             :                                 delivered = true;
    1464           0 :                         else if (err != -ESRCH)
    1465           0 :                                 goto error;
    1466             :                 }
    1467             : 
    1468           1 :                 prev = net;
    1469             :         }
    1470             : 
    1471           1 :         err = nlmsg_multicast(prev->genl_sock, skb, portid, group, flags);
    1472           1 :         if (!err)
    1473             :                 delivered = true;
    1474           1 :         else if (err != -ESRCH)
    1475             :                 return err;
    1476           1 :         return delivered ? 0 : -ESRCH;
    1477           0 :  error:
    1478           0 :         kfree_skb(skb);
    1479           0 :         return err;
    1480             : }
    1481             : 
    1482           1 : int genlmsg_multicast_allns(const struct genl_family *family,
    1483             :                             struct sk_buff *skb, u32 portid,
    1484             :                             unsigned int group, gfp_t flags)
    1485             : {
    1486           1 :         if (WARN_ON_ONCE(group >= family->n_mcgrps))
    1487             :                 return -EINVAL;
    1488           1 :         group = family->mcgrp_offset + group;
    1489           1 :         return genlmsg_mcast(skb, portid, group, flags);
    1490             : }
    1491             : EXPORT_SYMBOL(genlmsg_multicast_allns);
    1492             : 
    1493           0 : void genl_notify(const struct genl_family *family, struct sk_buff *skb,
    1494             :                  struct genl_info *info, u32 group, gfp_t flags)
    1495             : {
    1496           0 :         struct net *net = genl_info_net(info);
    1497           0 :         struct sock *sk = net->genl_sock;
    1498           0 :         int report = 0;
    1499             : 
    1500           0 :         if (info->nlhdr)
    1501           0 :                 report = nlmsg_report(info->nlhdr);
    1502             : 
    1503           0 :         if (WARN_ON_ONCE(group >= family->n_mcgrps))
    1504             :                 return;
    1505           0 :         group = family->mcgrp_offset + group;
    1506           0 :         nlmsg_notify(sk, skb, info->snd_portid, group, report, flags);
    1507             : }
    1508             : EXPORT_SYMBOL(genl_notify);

Generated by: LCOV version 1.14