]> git.ipfire.org Git - thirdparty/iproute2.git/commitdiff
libnetlink: fix socket leak in rtnl_open_byproto()
authorMaxim Petrov <mmrmaximuzz@gmail.com>
Tue, 8 Feb 2022 17:20:45 +0000 (20:20 +0300)
committerStephen Hemminger <stephen@networkplumber.org>
Fri, 11 Feb 2022 19:38:51 +0000 (11:38 -0800)
rtnl_open_byproto() does not close the opened socket in case of
errors, and the socket is returned to the caller in the `fd` field of
the struct. However, none of the callers care about the socket, so
close it in the function immediately to avoid any potential resource
leaks.

Signed-off-by: Maxim Petrov <mmrmaximuzz@gmail.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
lib/libnetlink.c

index 7e977a6762f8aa0edf2e49607cbd66248c4b565c..6d1b11876dc4c8706e3148a7d26d0137f8f9735b 100644 (file)
@@ -210,13 +210,13 @@ int rtnl_open_byproto(struct rtnl_handle *rth, unsigned int subscriptions,
        if (setsockopt(rth->fd, SOL_SOCKET, SO_SNDBUF,
                       &sndbuf, sizeof(sndbuf)) < 0) {
                perror("SO_SNDBUF");
-               return -1;
+               goto err;
        }
 
        if (setsockopt(rth->fd, SOL_SOCKET, SO_RCVBUF,
                       &rcvbuf, sizeof(rcvbuf)) < 0) {
                perror("SO_RCVBUF");
-               return -1;
+               goto err;
        }
 
        /* Older kernels may no support extended ACK reporting */
@@ -230,25 +230,28 @@ int rtnl_open_byproto(struct rtnl_handle *rth, unsigned int subscriptions,
        if (bind(rth->fd, (struct sockaddr *)&rth->local,
                 sizeof(rth->local)) < 0) {
                perror("Cannot bind netlink socket");
-               return -1;
+               goto err;
        }
        addr_len = sizeof(rth->local);
        if (getsockname(rth->fd, (struct sockaddr *)&rth->local,
                        &addr_len) < 0) {
                perror("Cannot getsockname");
-               return -1;
+               goto err;
        }
        if (addr_len != sizeof(rth->local)) {
                fprintf(stderr, "Wrong address length %d\n", addr_len);
-               return -1;
+               goto err;
        }
        if (rth->local.nl_family != AF_NETLINK) {
                fprintf(stderr, "Wrong address family %d\n",
                        rth->local.nl_family);
-               return -1;
+               goto err;
        }
        rth->seq = time(NULL);
        return 0;
+err:
+       rtnl_close(rth);
+       return -1;
 }
 
 int rtnl_open(struct rtnl_handle *rth, unsigned int subscriptions)