netlink: fix potential infinite loops
authorHans Dedecker <dedeckeh@gmail.com>
Mon, 23 Sep 2019 20:06:00 +0000 (22:06 +0200)
committerHans Dedecker <dedeckeh@gmail.com>
Tue, 1 Oct 2019 20:31:14 +0000 (22:31 +0200)
Fix potential infinite loops by checking the return code of
nl_send_auto_complete; if nl_send_auto_complete fails pending
will always have the value 1 as the finish callback will not
be called resulting into an infinite loop

Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
src/netlink.c

index 1a7534d83191eea4d31158c29e6694c6e2e098a6..39f6245ec82d35bbd8c9a2d371a4d8cbfe4a789b 100644 (file)
@@ -655,14 +655,16 @@ ssize_t netlink_get_interface_addrs(int ifindex, bool v6, struct odhcpd_ipaddr *
        nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_addr_finish, &ctxt);
        nl_cb_err(cb, NL_CB_CUSTOM, cb_addr_error, &ctxt);
 
-       nl_send_auto_complete(rtnl_socket, msg);
+       ctxt.ret = nl_send_auto_complete(rtnl_socket, msg);
+       if (ctxt.ret < 0)
+               goto free;
+
+       ctxt.ret = 0;
        while (ctxt.pending > 0)
                nl_recvmsgs(rtnl_socket, cb);
 
-       nlmsg_free(msg);
-
        if (ctxt.ret <= 0)
-               goto out;
+               goto free;
 
        time_t now = odhcpd_time();
        struct odhcpd_ipaddr *addr = *addrs;
@@ -677,6 +679,8 @@ ssize_t netlink_get_interface_addrs(int ifindex, bool v6, struct odhcpd_ipaddr *
                        addr[i].valid += now;
        }
 
+free:
+       nlmsg_free(msg);
 out:
        nl_cb_put(cb);
 
@@ -778,12 +782,15 @@ int netlink_get_interface_proxy_neigh(int ifindex, const struct in6_addr *addr)
        nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_proxy_neigh_finish, &ctxt);
        nl_cb_err(cb, NL_CB_CUSTOM, cb_proxy_neigh_error, &ctxt);
 
-       nl_send_auto_complete(rtnl_socket, msg);
+       ctxt.ret = nl_send_auto_complete(rtnl_socket, msg);
+       if (ctxt.ret < 0)
+               goto free;
+
        while (ctxt.pending > 0)
                nl_recvmsgs(rtnl_socket, cb);
 
+free:
        nlmsg_free(msg);
-
 out:
        nl_cb_put(cb);