[git commit branch/1_28_stable] ip: fix crash in "ip neigh show"

Denys Vlasenko vda.linux at googlemail.com
Wed Feb 14 16:38:40 UTC 2018


commit: https://git.busybox.net/busybox/commit/?id=f5b9a2267803bcb1dad5e902dcdfeefb65a112c3
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/1_28_stable

parse_rtattr() was using tb[] array without initializing it.

Based on patch by Balaji Punnuru <balaji_punnuru at cable.comcast.com>

function                                             old     new   delta
parse_rtattr                                          85     107     +22
print_route                                         1630    1617     -13
print_linkinfo                                       807     794     -13
iproute_get                                          835     822     -13
print_rule                                           680     665     -15
ll_remember_index                                    263     248     -15
print_addrinfo                                      1223    1197     -26
ipaddr_list_or_flush                                1253    1223     -30
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/7 up/down: 22/-125)          Total: -103 bytes

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 networking/libiproute/ipaddress.c  |  6 +++---
 networking/libiproute/ipneigh.c    | 10 ++++++----
 networking/libiproute/iproute.c    |  4 ++--
 networking/libiproute/iprule.c     |  2 +-
 networking/libiproute/libnetlink.c |  2 ++
 networking/libiproute/ll_map.c     |  2 +-
 networking/tc.c                    | 22 +++++++++++++---------
 7 files changed, 28 insertions(+), 20 deletions(-)

diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c
index 921ecf0d9..d7f888176 100644
--- a/networking/libiproute/ipaddress.c
+++ b/networking/libiproute/ipaddress.c
@@ -113,7 +113,7 @@ static NOINLINE int print_linkinfo(const struct nlmsghdr *n)
 	if (G_filter.up && !(ifi->ifi_flags & IFF_UP))
 		return 0;
 
-	memset(tb, 0, sizeof(tb));
+	//memset(tb, 0, sizeof(tb)); - parse_rtattr does this
 	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
 	if (tb[IFLA_IFNAME] == NULL) {
 		bb_error_msg("nil ifname");
@@ -227,7 +227,7 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM,
 	if (G_filter.flushb && n->nlmsg_type != RTM_NEWADDR)
 		return 0;
 
-	memset(rta_tb, 0, sizeof(rta_tb));
+	//memset(rta_tb, 0, sizeof(rta_tb)); - parse_rtattr does this
 	parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa)));
 
 	if (!rta_tb[IFA_LOCAL])
@@ -535,7 +535,7 @@ int FAST_FUNC ipaddr_list_or_flush(char **argv, int flush)
 					continue;
 				if (G_filter.pfx.family || G_filter.label) {
 					struct rtattr *tb[IFA_MAX+1];
-					memset(tb, 0, sizeof(tb));
+					//memset(tb, 0, sizeof(tb)); - parse_rtattr does this
 					parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), IFA_PAYLOAD(n));
 					if (!tb[IFA_LOCAL])
 						tb[IFA_LOCAL] = tb[IFA_ADDRESS];
diff --git a/networking/libiproute/ipneigh.c b/networking/libiproute/ipneigh.c
index 1cd90d707..f572414e9 100644
--- a/networking/libiproute/ipneigh.c
+++ b/networking/libiproute/ipneigh.c
@@ -110,11 +110,13 @@ static int FAST_FUNC print_neigh(const struct sockaddr_nl *who UNUSED_PARAM,
 		return 0;
 	if (G_filter.index && G_filter.index != r->ndm_ifindex)
 		return 0;
-	if (!(G_filter.state&r->ndm_state) &&
-	    !(r->ndm_flags & NTF_PROXY) &&
-	    (r->ndm_state || !(G_filter.state & 0x100)) &&
-	    (r->ndm_family != AF_DECnet))
+	if (!(G_filter.state&r->ndm_state)
+	 && !(r->ndm_flags & NTF_PROXY)
+	 && (r->ndm_state || !(G_filter.state & 0x100))
+	 && (r->ndm_family != AF_DECnet)
+	) {
 		return 0;
+	}
 
 	parse_rtattr(tb, NDA_MAX, NDA_RTA(r), n->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
 
diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c
index 95dafe183..2a8610ea6 100644
--- a/networking/libiproute/iproute.c
+++ b/networking/libiproute/iproute.c
@@ -83,7 +83,7 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM,
 	if (len < 0)
 		bb_error_msg_and_die("wrong nlmsg len %d", len);
 
-	memset(tb, 0, sizeof(tb));
+	//memset(tb, 0, sizeof(tb)); - parse_rtattr does this
 	parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
 
 #if HAVE_RTA_TABLE
@@ -1081,7 +1081,7 @@ static int iproute_get(char **argv)
 			bb_error_msg_and_die("wrong len %d", len);
 		}
 
-		memset(tb, 0, sizeof(tb));
+		//memset(tb, 0, sizeof(tb)); - parse_rtattr does this
 		parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
 
 		if (tb[RTA_PREFSRC]) {
diff --git a/networking/libiproute/iprule.c b/networking/libiproute/iprule.c
index 53b11e16c..0ce0dfeef 100644
--- a/networking/libiproute/iprule.c
+++ b/networking/libiproute/iprule.c
@@ -63,7 +63,7 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM,
 	if (len < 0)
 		return -1;
 
-	memset(tb, 0, sizeof(tb));
+	//memset(tb, 0, sizeof(tb)); - parse_rtattr does this
 	parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
 
 	if (r->rtm_family == AF_INET)
diff --git a/networking/libiproute/libnetlink.c b/networking/libiproute/libnetlink.c
index 3f0f70326..f08d862d0 100644
--- a/networking/libiproute/libnetlink.c
+++ b/networking/libiproute/libnetlink.c
@@ -401,6 +401,8 @@ int FAST_FUNC rta_addattr_l(struct rtattr *rta, int maxlen, int type, void *data
 
 void FAST_FUNC parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len)
 {
+	memset(tb, 0, (max + 1) * sizeof(tb[0]));
+
 	while (RTA_OK(rta, len)) {
 		if (rta->rta_type <= max) {
 			tb[rta->rta_type] = rta;
diff --git a/networking/libiproute/ll_map.c b/networking/libiproute/ll_map.c
index be88a04e8..66401da77 100644
--- a/networking/libiproute/ll_map.c
+++ b/networking/libiproute/ll_map.c
@@ -51,7 +51,7 @@ int FAST_FUNC ll_remember_index(const struct sockaddr_nl *who UNUSED_PARAM,
 	if (n->nlmsg_len < NLMSG_LENGTH(sizeof(ifi)))
 		return -1;
 
-	memset(tb, 0, sizeof(tb));
+	//memset(tb, 0, sizeof(tb)); - parse_rtattr does this
 	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), IFLA_PAYLOAD(n));
 	if (tb[IFLA_IFNAME] == NULL)
 		return 0;
diff --git a/networking/tc.c b/networking/tc.c
index 23abf636c..284c93098 100644
--- a/networking/tc.c
+++ b/networking/tc.c
@@ -57,17 +57,21 @@
 
 /* nullifies tb on error */
 #define __parse_rtattr_nested_compat(tb, max, rta, len) \
-	({if ((RTA_PAYLOAD(rta) >= len) && \
-		 (RTA_PAYLOAD(rta) >= RTA_ALIGN(len) + sizeof(struct rtattr))) { \
-			rta = RTA_DATA(rta) + RTA_ALIGN(len); \
-			parse_rtattr_nested(tb, max, rta); \
-	  } else \
-			memset(tb, 0, sizeof(struct rtattr *) * (max + 1)); \
-	})
+({ \
+	if ((RTA_PAYLOAD(rta) >= len) \
+	 && (RTA_PAYLOAD(rta) >= RTA_ALIGN(len) + sizeof(struct rtattr)) \
+	) { \
+		rta = RTA_DATA(rta) + RTA_ALIGN(len); \
+		parse_rtattr_nested(tb, max, rta); \
+	} else \
+		memset(tb, 0, sizeof(struct rtattr *) * (max + 1)); \
+})
 
 #define parse_rtattr_nested_compat(tb, max, rta, data, len) \
-	({data = RTA_PAYLOAD(rta) >= len ? RTA_DATA(rta) : NULL; \
-	__parse_rtattr_nested_compat(tb, max, rta, len); })
+({ \
+	data = RTA_PAYLOAD(rta) >= len ? RTA_DATA(rta) : NULL; \
+	__parse_rtattr_nested_compat(tb, max, rta, len); \
+})
 
 #define show_details (0) /* not implemented. Does anyone need it? */
 #define use_iec (0) /* not currently documented in the upstream manpage */


More information about the busybox-cvs mailing list