devlink: don't allocate attrs on the stack
authorJakub Kicinski <jakub.kicinski@netronome.com>
Mon, 11 Feb 2019 03:35:28 +0000 (19:35 -0800)
committerDavid S. Miller <davem@davemloft.net>
Tue, 12 Feb 2019 04:39:56 +0000 (20:39 -0800)
Number of devlink attributes has grown over 128, causing the
following warning:

../net/core/devlink.c: In function ‘devlink_nl_cmd_region_read_dumpit’:
../net/core/devlink.c:3740:1: warning: the frame size of 1064 bytes is larger than 1024 bytes [-Wframe-larger-than=]
 }
  ^

Since the number of attributes is only going to grow allocate
the array dynamically.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/core/devlink.c

index 61fab0dc0166ee5e27262835f1876dea4a090280..ec02459eea94020489dee1d6df800e4149edca3e 100644 (file)
@@ -3629,26 +3629,30 @@ static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
                                             struct netlink_callback *cb)
 {
        u64 ret_offset, start_offset, end_offset = 0;
-       struct nlattr *attrs[DEVLINK_ATTR_MAX + 1];
        const struct genl_ops *ops = cb->data;
        struct devlink_region *region;
        struct nlattr *chunks_attr;
        const char *region_name;
        struct devlink *devlink;
+       struct nlattr **attrs;
        bool dump = true;
        void *hdr;
        int err;
 
        start_offset = *((u64 *)&cb->args[0]);
 
+       attrs = kmalloc_array(DEVLINK_ATTR_MAX + 1, sizeof(*attrs), GFP_KERNEL);
+       if (!attrs)
+               return -ENOMEM;
+
        err = nlmsg_parse(cb->nlh, GENL_HDRLEN + devlink_nl_family.hdrsize,
                          attrs, DEVLINK_ATTR_MAX, ops->policy, cb->extack);
        if (err)
-               goto out;
+               goto out_free;
 
        devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs);
        if (IS_ERR(devlink))
-               goto out;
+               goto out_free;
 
        mutex_lock(&devlink_mutex);
        mutex_lock(&devlink->lock);
@@ -3710,6 +3714,7 @@ static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
        genlmsg_end(skb, hdr);
        mutex_unlock(&devlink->lock);
        mutex_unlock(&devlink_mutex);
+       kfree(attrs);
 
        return skb->len;
 
@@ -3718,7 +3723,8 @@ nla_put_failure:
 out_unlock:
        mutex_unlock(&devlink->lock);
        mutex_unlock(&devlink_mutex);
-out:
+out_free:
+       kfree(attrs);
        return 0;
 }