]> granicus.if.org Git - libnl/commitdiff
lib/genl: avoid VLA in cmd_msg_parser()
authorThomas Haller <thaller@redhat.com>
Fri, 9 Aug 2019 11:12:30 +0000 (13:12 +0200)
committerThomas Haller <thaller@redhat.com>
Fri, 9 Aug 2019 14:48:55 +0000 (16:48 +0200)
We want to build with -Wvla, because VLAs interfere with static asserts
(if the condition of a static assert is not actually static, then VLAs
make it silently pass).

Also, VLAs should be avoided because we want to be in contol how much
we allocate on the stack.

lib/genl/mngt.c

index ebfe85ed870d38466b706e5cdd36fa10718fcf3f..0e0aeefb23e3884bce3291e8832e21108773f9a5 100644 (file)
@@ -26,6 +26,8 @@
 #include <netlink/genl/ctrl.h>
 #include <netlink/utils.h>
 
+#include "netlink-private/utils.h"
+
 /** @cond SKIP */
 
 static NL_LIST_HEAD(genl_ops_list);
@@ -45,41 +47,45 @@ static struct genl_cmd *lookup_cmd(struct genl_ops *ops, int cmd_id)
 }
 
 static int cmd_msg_parser(struct sockaddr_nl *who, struct nlmsghdr *nlh,
-                         struct genl_ops *ops, struct nl_cache_ops *cache_ops, void *arg)
+                          struct genl_ops *ops, struct nl_cache_ops *cache_ops, void *arg)
 {
+       _nl_auto_free struct nlattr **tb_free = NULL;
        int err;
        struct genlmsghdr *ghdr;
        struct genl_cmd *cmd;
+       struct nlattr **tb;
 
        ghdr = genlmsg_hdr(nlh);
 
-       if (!(cmd = lookup_cmd(ops, ghdr->cmd))) {
-               err = -NLE_MSGTYPE_NOSUPPORT;
-               goto errout;
-       }
+       if (!(cmd = lookup_cmd(ops, ghdr->cmd)))
+               return -NLE_MSGTYPE_NOSUPPORT;
 
        if (cmd->c_msg_parser == NULL)
-               err = -NLE_OPNOTSUPP;
-       else {
-               struct nlattr *tb[cmd->c_maxattr + 1];
+               return -NLE_OPNOTSUPP;
+
+       tb = _nl_malloc_maybe_a (300, ((size_t) cmd->c_maxattr) + 1, &tb_free);
+       if (!tb)
+               return -NLE_NOMEM;
+
+       err = nlmsg_parse(nlh,
+                         GENL_HDRSIZE(ops->o_hdrsize),
+                         tb,
+                         cmd->c_maxattr,
+                         cmd->c_attr_policy);
+       if (err < 0)
+               return err;
+
+       {
                struct genl_info info = {
-                       .who = who,
-                       .nlh = nlh,
+                       .who     = who,
+                       .nlh     = nlh,
                        .genlhdr = ghdr,
                        .userhdr = genlmsg_user_hdr(ghdr),
-                       .attrs = tb,
+                       .attrs   = tb,
                };
 
-               err = nlmsg_parse(nlh, GENL_HDRSIZE(ops->o_hdrsize), tb, cmd->c_maxattr,
-                                 cmd->c_attr_policy);
-               if (err < 0)
-                       goto errout;
-
-               err = cmd->c_msg_parser(cache_ops, cmd, &info, arg);
+               return cmd->c_msg_parser(cache_ops, cmd, &info, arg);
        }
-errout:
-       return err;
-
 }
 
 static int genl_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,