summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-08-09 11:12:30 (GMT)
committerThomas Haller <thaller@redhat.com>2019-08-09 14:48:55 (GMT)
commit7d3991b87b59b538cb98a7b11646760f23a7c19b (patch)
tree7e76540f0af2828f36eeff19df309c62443b3944
parent6c574429d900d75cb8d77e65bf1d3ae2a87bf44a (diff)
downloadlibnl-7d3991b87b59b538cb98a7b11646760f23a7c19b.zip
libnl-7d3991b87b59b538cb98a7b11646760f23a7c19b.tar.gz
libnl-7d3991b87b59b538cb98a7b11646760f23a7c19b.tar.bz2
lib/genl: avoid VLA in cmd_msg_parser()
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.
-rw-r--r--lib/genl/mngt.c46
1 files changed, 26 insertions, 20 deletions
diff --git a/lib/genl/mngt.c b/lib/genl/mngt.c
index ebfe85e..0e0aeef 100644
--- a/lib/genl/mngt.c
+++ b/lib/genl/mngt.c
@@ -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,