Browse Source

system-linux: set pending to 0 on ifindex found or error for if_get_master

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>
Christian Marangi 4 months ago
parent
commit
66a7652176
1 changed files with 13 additions and 7 deletions
  1. 13 7
      system-linux.c

+ 13 - 7
system-linux.c

@@ -1730,7 +1730,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,
@@ -1744,6 +1744,7 @@ static void if_get_master_dsa_linkinfo_attr(struct if_get_master_data *data,
 			continue;
 
 		data->master_ifindex = *(__u32 *)RTA_DATA(cur);
+		return;
 	}
 }
 
@@ -1758,7 +1759,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);
@@ -1786,8 +1787,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);
 	}
@@ -1798,14 +1802,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;
 }
 
@@ -1820,7 +1826,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;
 
@@ -1843,7 +1849,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)