[PATCH 2/2] route: detect missing cfgid in rtnl_link_inet_get_conf()

Thomas Haller thaller at redhat.com
Wed Mar 19 09:49:07 EDT 2014


If the netlink message for IFLA_INET_CONF contains less then
IPV4_DEVCONF_MAX entires, the last entries in i_conf are unset.
Modify rtnl_link_inet_get_conf() to return -EINVAL when accessing
an unset cfgid.

Signed-off-by: Thomas Haller <thaller at redhat.com>
---
 lib/route/link/inet.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/lib/route/link/inet.c b/lib/route/link/inet.c
index d29ada3..c8e72c4 100644
--- a/lib/route/link/inet.c
+++ b/lib/route/link/inet.c
@@ -106,13 +106,17 @@ static int inet_parse_af(struct rtnl_link *link, struct nlattr *attr, void *data
 		return err;
 
 	if (tb[IFLA_INET_CONF]) {
-		int len = nla_len(tb[IFLA_INET_CONF]);
+		int i, len = nla_len(tb[IFLA_INET_CONF]);
 
 		if (len % sizeof(id->i_conf[0]))
 			return -EINVAL;
-		memset(&id->i_conf, 0, sizeof(id->i_conf));
+		len /= sizeof(id->i_conf[0]);
+
+		for (i = 0; i < IPV4_DEVCONF_MAX; i++)
+			id->i_confset[i] = (i < len);
 		nla_memcpy(&id->i_conf, tb[IFLA_INET_CONF], sizeof(id->i_conf));
-	}
+	} else
+		memset(&id->i_confset, 0, sizeof(id->i_confset));
 
 	return 0;
 }
@@ -190,7 +194,7 @@ static void inet_dump_details(struct rtnl_link *link,
 	for (i = 0; i < IPV4_DEVCONF_MAX; i++) {
 		nl_dump_line(p, "%-19s %3u",
 			rtnl_link_inet_devconf2str(i+1, buf, sizeof(buf)),
-			id->i_conf[i]);
+			id->i_confset[i] ? id->i_conf[i] : 0);
 
 		if (++n == 3) {
 			nl_dump(p, "\n");
@@ -226,6 +230,8 @@ static struct rtnl_link_af_ops inet_ops = {
  * @return 0 on success or a negative error code.
  * @return -NLE_RANGE cfgid is out of range, 1..IPV4_DEVCONF_MAX
  * @return -NLE_NOATTR configuration setting not available
+ * @return -NLE_INVAL cfgid not set. If the link was received via netlink,
+ *                    it means that the cfgid is not supported.
  */
 int rtnl_link_inet_get_conf(struct rtnl_link *link, const unsigned int cfgid,
 			    uint32_t *res)
@@ -238,6 +244,8 @@ int rtnl_link_inet_get_conf(struct rtnl_link *link, const unsigned int cfgid,
 	if (!(id = rtnl_link_af_alloc(link, &inet_ops)))
 		return -NLE_NOATTR;
 
+	if (!id->i_confset[cfgid - 1])
+		return -NLE_INVAL;
 	*res = id->i_conf[cfgid - 1];
 
 	return 0;
-- 
1.8.5.3




More information about the libnl mailing list