system-linux: set pending to 0 on ifindex found or error for if_get_master
authorChristian Marangi <ansuelsmth@gmail.com>
Sun, 17 Dec 2023 15:47:16 +0000 (16:47 +0100)
committerFelix Fietkau <nbd@nbd.name>
Thu, 4 Jan 2024 12:35:39 +0000 (13:35 +0100)
Fix Coverity Defect 1559194 reporting an Infinite loop when
data->pending is not set to 0 on finishing the callback.

While this is a false-positive report as ACK is always called, this is a
good time to optimize the code and make the callback exit early if we
find the ifindex for the DSA conduit.

Correctly set pending to 0 on ifindex found or error for if_get_master
valid netlink callback.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
system-linux.c

index f4dbc181d18535e029e4f8d7085f82f340814c74..e6160d5b25e93116fcea923849ba6462aceec63b 100644 (file)
@@ -1719,7 +1719,7 @@ int system_vlandev_del(struct device *vlandev)
 struct if_get_master_data {
        int ifindex;
        int master_ifindex;
-       int pending;
+       bool pending;
 };
 
 static void if_get_master_dsa_linkinfo_attr(struct if_get_master_data *data,
@@ -1733,6 +1733,7 @@ static void if_get_master_dsa_linkinfo_attr(struct if_get_master_data *data,
                        continue;
 
                data->master_ifindex = *(__u32 *)RTA_DATA(cur);
+               return;
        }
 }
 
@@ -1747,7 +1748,7 @@ static void if_get_master_linkinfo_attr(struct if_get_master_data *data,
                        continue;
 
                if (cur->rta_type == IFLA_INFO_KIND && strcmp("dsa", (char *)RTA_DATA(cur)))
-                       break;
+                       return;
 
                if (cur->rta_type == IFLA_INFO_DATA)
                        if_get_master_dsa_linkinfo_attr(data, cur);
@@ -1775,8 +1776,11 @@ static int cb_if_get_master_valid(struct nl_msg *msg, void *arg)
        rem = nh->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi));
 
        while (RTA_OK(attr, rem)) {
-               if (attr->rta_type == IFLA_LINKINFO)
+               if (attr->rta_type == IFLA_LINKINFO) {
                        if_get_master_linkinfo_attr(data, attr);
+                       data->pending = false;
+                       break;
+               }
 
                attr = RTA_NEXT(attr, rem);
        }
@@ -1787,14 +1791,16 @@ static int cb_if_get_master_valid(struct nl_msg *msg, void *arg)
 static int cb_if_get_master_ack(struct nl_msg *msg, void *arg)
 {
        struct if_get_master_data *data = (struct if_get_master_data *)arg;
-       data->pending = 0;
+       data->pending = false;
+
        return NL_STOP;
 }
 
 static int cb_if_get_master_error(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
 {
        struct if_get_master_data *data = (struct if_get_master_data *)arg;
-       data->pending = 0;
+       data->pending = false;
+
        return NL_STOP;
 }
 
@@ -1809,7 +1815,7 @@ static int system_if_get_master_ifindex(struct device *dev)
        struct if_get_master_data data = {
                .ifindex = if_nametoindex(dev->ifname),
                .master_ifindex = -1,
-               .pending = 1,
+               .pending = true,
        };
        int ret = -1;
 
@@ -1832,7 +1838,7 @@ static int system_if_get_master_ifindex(struct device *dev)
        if (ret < 0)
                goto free;
 
-       while (data.pending > 0)
+       while (data.pending)
                nl_recvmsgs(sock_rtnl, cb);
 
        if (data.master_ifindex >= 0)