common/mlx5: fix netlink buffer allocation from stack
authorViacheslav Ovsiienko <viacheslavo@mellanox.com>
Thu, 14 May 2020 07:11:12 +0000 (07:11 +0000)
committerFerruh Yigit <ferruh.yigit@intel.com>
Mon, 18 May 2020 18:35:57 +0000 (20:35 +0200)
The buffer size to receive netlink reply messages is relatively
large (32K), and it is allocated on the stack and it might
break in application is using smaller per-thread stacks.
This patch allocates temporary buffer from heap.

Fixes: ccdcba53a3f4 ("net/mlx5: use Netlink to add/remove MAC addresses")
Cc: stable@dpdk.org
Reported-by: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
Acked-by: Matan Azrad <matan@mellanox.com>
drivers/common/mlx5/mlx5_nl.c

index 65efcd3..1a1033a 100644 (file)
@@ -330,10 +330,10 @@ mlx5_nl_recv(int nlsk_fd, uint32_t sn, int (*cb)(struct nlmsghdr *, void *arg),
             void *arg)
 {
        struct sockaddr_nl sa;
-       char buf[MLX5_RECV_BUF_SIZE];
+       void *buf = malloc(MLX5_RECV_BUF_SIZE);
        struct iovec iov = {
                .iov_base = buf,
-               .iov_len = sizeof(buf),
+               .iov_len = MLX5_RECV_BUF_SIZE,
        };
        struct msghdr msg = {
                .msg_name = &sa,
@@ -345,6 +345,10 @@ mlx5_nl_recv(int nlsk_fd, uint32_t sn, int (*cb)(struct nlmsghdr *, void *arg),
        int multipart = 0;
        int ret = 0;
 
+       if (!buf) {
+               rte_errno = ENOMEM;
+               return -rte_errno;
+       }
        do {
                struct nlmsghdr *nh;
                int recv_bytes = 0;
@@ -353,7 +357,8 @@ mlx5_nl_recv(int nlsk_fd, uint32_t sn, int (*cb)(struct nlmsghdr *, void *arg),
                        recv_bytes = recvmsg(nlsk_fd, &msg, 0);
                        if (recv_bytes == -1) {
                                rte_errno = errno;
-                               return -rte_errno;
+                               ret = -rte_errno;
+                               goto exit;
                        }
                        nh = (struct nlmsghdr *)buf;
                } while (nh->nlmsg_seq != sn);
@@ -365,24 +370,30 @@ mlx5_nl_recv(int nlsk_fd, uint32_t sn, int (*cb)(struct nlmsghdr *, void *arg),
 
                                if (err_data->error < 0) {
                                        rte_errno = -err_data->error;
-                                       return -rte_errno;
+                                       ret = -rte_errno;
+                                       goto exit;
                                }
                                /* Ack message. */
-                               return 0;
+                               ret = 0;
+                               goto exit;
                        }
                        /* Multi-part msgs and their trailing DONE message. */
                        if (nh->nlmsg_flags & NLM_F_MULTI) {
-                               if (nh->nlmsg_type == NLMSG_DONE)
-                                       return 0;
+                               if (nh->nlmsg_type == NLMSG_DONE) {
+                                       ret =  0;
+                                       goto exit;
+                               }
                                multipart = 1;
                        }
                        if (cb) {
                                ret = cb(nh, arg);
                                if (ret < 0)
-                                       return ret;
+                                       goto exit;
                        }
                }
        } while (multipart);
+exit:
+       free(buf);
        return ret;
 }