aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-02-08 08:42:37 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-02-14 17:38:40 +0100
commitf5b9a2267803bcb1dad5e902dcdfeefb65a112c3 (patch)
treecf523d028046012a1da3f7926435e776b438c59c
parent112392232028fa2ce215043e7f9cf78f7ff74afe (diff)
downloadbusybox-w32-f5b9a2267803bcb1dad5e902dcdfeefb65a112c3.tar.gz
busybox-w32-f5b9a2267803bcb1dad5e902dcdfeefb65a112c3.tar.bz2
busybox-w32-f5b9a2267803bcb1dad5e902dcdfeefb65a112c3.zip
ip: fix crash in "ip neigh show"
parse_rtattr() was using tb[] array without initializing it. Based on patch by Balaji Punnuru <balaji_punnuru@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@googlemail.com>
-rw-r--r--networking/libiproute/ipaddress.c6
-rw-r--r--networking/libiproute/ipneigh.c10
-rw-r--r--networking/libiproute/iproute.c4
-rw-r--r--networking/libiproute/iprule.c2
-rw-r--r--networking/libiproute/libnetlink.c2
-rw-r--r--networking/libiproute/ll_map.c2
-rw-r--r--networking/tc.c22
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)
113 if (G_filter.up && !(ifi->ifi_flags & IFF_UP)) 113 if (G_filter.up && !(ifi->ifi_flags & IFF_UP))
114 return 0; 114 return 0;
115 115
116 memset(tb, 0, sizeof(tb)); 116 //memset(tb, 0, sizeof(tb)); - parse_rtattr does this
117 parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len); 117 parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
118 if (tb[IFLA_IFNAME] == NULL) { 118 if (tb[IFLA_IFNAME] == NULL) {
119 bb_error_msg("nil ifname"); 119 bb_error_msg("nil ifname");
@@ -227,7 +227,7 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM,
227 if (G_filter.flushb && n->nlmsg_type != RTM_NEWADDR) 227 if (G_filter.flushb && n->nlmsg_type != RTM_NEWADDR)
228 return 0; 228 return 0;
229 229
230 memset(rta_tb, 0, sizeof(rta_tb)); 230 //memset(rta_tb, 0, sizeof(rta_tb)); - parse_rtattr does this
231 parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa))); 231 parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa)));
232 232
233 if (!rta_tb[IFA_LOCAL]) 233 if (!rta_tb[IFA_LOCAL])
@@ -535,7 +535,7 @@ int FAST_FUNC ipaddr_list_or_flush(char **argv, int flush)
535 continue; 535 continue;
536 if (G_filter.pfx.family || G_filter.label) { 536 if (G_filter.pfx.family || G_filter.label) {
537 struct rtattr *tb[IFA_MAX+1]; 537 struct rtattr *tb[IFA_MAX+1];
538 memset(tb, 0, sizeof(tb)); 538 //memset(tb, 0, sizeof(tb)); - parse_rtattr does this
539 parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), IFA_PAYLOAD(n)); 539 parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), IFA_PAYLOAD(n));
540 if (!tb[IFA_LOCAL]) 540 if (!tb[IFA_LOCAL])
541 tb[IFA_LOCAL] = tb[IFA_ADDRESS]; 541 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,
110 return 0; 110 return 0;
111 if (G_filter.index && G_filter.index != r->ndm_ifindex) 111 if (G_filter.index && G_filter.index != r->ndm_ifindex)
112 return 0; 112 return 0;
113 if (!(G_filter.state&r->ndm_state) && 113 if (!(G_filter.state&r->ndm_state)
114 !(r->ndm_flags & NTF_PROXY) && 114 && !(r->ndm_flags & NTF_PROXY)
115 (r->ndm_state || !(G_filter.state & 0x100)) && 115 && (r->ndm_state || !(G_filter.state & 0x100))
116 (r->ndm_family != AF_DECnet)) 116 && (r->ndm_family != AF_DECnet)
117 ) {
117 return 0; 118 return 0;
119 }
118 120
119 parse_rtattr(tb, NDA_MAX, NDA_RTA(r), n->nlmsg_len - NLMSG_LENGTH(sizeof(*r))); 121 parse_rtattr(tb, NDA_MAX, NDA_RTA(r), n->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
120 122
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,
83 if (len < 0) 83 if (len < 0)
84 bb_error_msg_and_die("wrong nlmsg len %d", len); 84 bb_error_msg_and_die("wrong nlmsg len %d", len);
85 85
86 memset(tb, 0, sizeof(tb)); 86 //memset(tb, 0, sizeof(tb)); - parse_rtattr does this
87 parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len); 87 parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
88 88
89#if HAVE_RTA_TABLE 89#if HAVE_RTA_TABLE
@@ -1081,7 +1081,7 @@ static int iproute_get(char **argv)
1081 bb_error_msg_and_die("wrong len %d", len); 1081 bb_error_msg_and_die("wrong len %d", len);
1082 } 1082 }
1083 1083
1084 memset(tb, 0, sizeof(tb)); 1084 //memset(tb, 0, sizeof(tb)); - parse_rtattr does this
1085 parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len); 1085 parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
1086 1086
1087 if (tb[RTA_PREFSRC]) { 1087 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,
63 if (len < 0) 63 if (len < 0)
64 return -1; 64 return -1;
65 65
66 memset(tb, 0, sizeof(tb)); 66 //memset(tb, 0, sizeof(tb)); - parse_rtattr does this
67 parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len); 67 parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
68 68
69 if (r->rtm_family == AF_INET) 69 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
401 401
402void FAST_FUNC parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) 402void FAST_FUNC parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len)
403{ 403{
404 memset(tb, 0, (max + 1) * sizeof(tb[0]));
405
404 while (RTA_OK(rta, len)) { 406 while (RTA_OK(rta, len)) {
405 if (rta->rta_type <= max) { 407 if (rta->rta_type <= max) {
406 tb[rta->rta_type] = rta; 408 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,
51 if (n->nlmsg_len < NLMSG_LENGTH(sizeof(ifi))) 51 if (n->nlmsg_len < NLMSG_LENGTH(sizeof(ifi)))
52 return -1; 52 return -1;
53 53
54 memset(tb, 0, sizeof(tb)); 54 //memset(tb, 0, sizeof(tb)); - parse_rtattr does this
55 parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), IFLA_PAYLOAD(n)); 55 parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), IFLA_PAYLOAD(n));
56 if (tb[IFLA_IFNAME] == NULL) 56 if (tb[IFLA_IFNAME] == NULL)
57 return 0; 57 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 @@
57 57
58/* nullifies tb on error */ 58/* nullifies tb on error */
59#define __parse_rtattr_nested_compat(tb, max, rta, len) \ 59#define __parse_rtattr_nested_compat(tb, max, rta, len) \
60 ({if ((RTA_PAYLOAD(rta) >= len) && \ 60({ \
61 (RTA_PAYLOAD(rta) >= RTA_ALIGN(len) + sizeof(struct rtattr))) { \ 61 if ((RTA_PAYLOAD(rta) >= len) \
62 rta = RTA_DATA(rta) + RTA_ALIGN(len); \ 62 && (RTA_PAYLOAD(rta) >= RTA_ALIGN(len) + sizeof(struct rtattr)) \
63 parse_rtattr_nested(tb, max, rta); \ 63 ) { \
64 } else \ 64 rta = RTA_DATA(rta) + RTA_ALIGN(len); \
65 memset(tb, 0, sizeof(struct rtattr *) * (max + 1)); \ 65 parse_rtattr_nested(tb, max, rta); \
66 }) 66 } else \
67 memset(tb, 0, sizeof(struct rtattr *) * (max + 1)); \
68})
67 69
68#define parse_rtattr_nested_compat(tb, max, rta, data, len) \ 70#define parse_rtattr_nested_compat(tb, max, rta, data, len) \
69 ({data = RTA_PAYLOAD(rta) >= len ? RTA_DATA(rta) : NULL; \ 71({ \
70 __parse_rtattr_nested_compat(tb, max, rta, len); }) 72 data = RTA_PAYLOAD(rta) >= len ? RTA_DATA(rta) : NULL; \
73 __parse_rtattr_nested_compat(tb, max, rta, len); \
74})
71 75
72#define show_details (0) /* not implemented. Does anyone need it? */ 76#define show_details (0) /* not implemented. Does anyone need it? */
73#define use_iec (0) /* not currently documented in the upstream manpage */ 77#define use_iec (0) /* not currently documented in the upstream manpage */