[PATCH 1/2] route: do not enforce minlen in inet6_parse_protinfo() when parsing IFLA_INET6_CONF

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


Before, the attribute IFLA_INET6_CONF expected .minlen = DEVCONF_MAX * 4, where
DEVCONF_MAX was defined in a libnl internal header file. If the running
kernel was compiled using a different size (having fewer DEVCONF_* values), libnl
would reject the netlink messages as invalid.

Analog, do not require minlength IPV4_DEVCONF_MAX * 4 for inet_parse_af()
when parsing IFLA_INET_CONF.

https://bugzilla.redhat.com/show_bug.cgi?id=1062533

Signed-off-by: Thomas Haller <thaller at redhat.com>
---
 lib/route/link/inet.c  | 10 ++++++++--
 lib/route/link/inet6.c |  8 ++++++--
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/lib/route/link/inet.c b/lib/route/link/inet.c
index e2c867d..d29ada3 100644
--- a/lib/route/link/inet.c
+++ b/lib/route/link/inet.c
@@ -92,7 +92,7 @@ static void inet_free(struct rtnl_link *link, void *data)
 }
 
 static struct nla_policy inet_policy[IFLA_INET6_MAX+1] = {
-	[IFLA_INET_CONF]	= { .minlen = IPV4_DEVCONF_MAX * 4 },
+	[IFLA_INET_CONF]	= { .minlen = 4 },
 };
 
 static int inet_parse_af(struct rtnl_link *link, struct nlattr *attr, void *data)
@@ -105,8 +105,14 @@ static int inet_parse_af(struct rtnl_link *link, struct nlattr *attr, void *data
 	if (err < 0)
 		return err;
 
-	if (tb[IFLA_INET_CONF])
+	if (tb[IFLA_INET_CONF]) {
+		int 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));
 		nla_memcpy(&id->i_conf, tb[IFLA_INET_CONF], sizeof(id->i_conf));
+	}
 
 	return 0;
 }
diff --git a/lib/route/link/inet6.c b/lib/route/link/inet6.c
index 4c627bd..9c8f7a7 100644
--- a/lib/route/link/inet6.c
+++ b/lib/route/link/inet6.c
@@ -45,7 +45,7 @@ static void inet6_free(struct rtnl_link *link, void *data)
 static struct nla_policy inet6_policy[IFLA_INET6_MAX+1] = {
 	[IFLA_INET6_FLAGS]	= { .type = NLA_U32 },
 	[IFLA_INET6_CACHEINFO]	= { .minlen = sizeof(struct ifla_cacheinfo) },
-	[IFLA_INET6_CONF]	= { .minlen = DEVCONF_MAX * 4 },
+	[IFLA_INET6_CONF]	= { .minlen = 4 },
 	[IFLA_INET6_STATS]	= { .minlen = __IPSTATS_MIB_MAX * 8 },
 	[IFLA_INET6_ICMP6STATS]	= { .minlen = __ICMP6_MIB_MAX * 8 },
 };
@@ -68,9 +68,13 @@ static int inet6_parse_protinfo(struct rtnl_link *link, struct nlattr *attr,
 		nla_memcpy(&i6->i6_cacheinfo, tb[IFLA_INET6_CACHEINFO],
 			   sizeof(i6->i6_cacheinfo));
 
-	if (tb[IFLA_INET6_CONF])
+	if (tb[IFLA_INET6_CONF]) {
+		if (nla_len(tb[IFLA_INET6_CONF]) % sizeof(i6->i6_conf[0]))
+			return -EINVAL;
+		memset (&i6->i6_conf, 0, sizeof(i6->i6_conf));
 		nla_memcpy(&i6->i6_conf, tb[IFLA_INET6_CONF],
 			   sizeof(i6->i6_conf));
+	}
  
 	/*
 	 * Due to 32bit data alignment, these addresses must be copied to an
-- 
1.8.5.3




More information about the libnl mailing list