diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-02-08 08:42:37 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-02-08 08:42:37 +0100 |
commit | 68ae54243cacee6beeb69842c7d562435acd5ad1 (patch) | |
tree | 0991e9bfa88bcdff63be362ad62627aacf532b37 | |
parent | 237a900bc5654c865298b33a70dee60e2cd05dbc (diff) | |
download | busybox-w32-68ae54243cacee6beeb69842c7d562435acd5ad1.tar.gz busybox-w32-68ae54243cacee6beeb69842c7d562435acd5ad1.tar.bz2 busybox-w32-68ae54243cacee6beeb69842c7d562435acd5ad1.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.c | 6 | ||||
-rw-r--r-- | networking/libiproute/ipneigh.c | 10 | ||||
-rw-r--r-- | networking/libiproute/iproute.c | 4 | ||||
-rw-r--r-- | networking/libiproute/iprule.c | 2 | ||||
-rw-r--r-- | networking/libiproute/libnetlink.c | 2 | ||||
-rw-r--r-- | networking/libiproute/ll_map.c | 2 | ||||
-rw-r--r-- | 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) | |||
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 | ||
402 | void FAST_FUNC parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) | 402 | void 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 4e375a066..4fa3e47bf 100644 --- a/networking/tc.c +++ b/networking/tc.c | |||
@@ -66,17 +66,21 @@ enum | |||
66 | 66 | ||
67 | /* nullifies tb on error */ | 67 | /* nullifies tb on error */ |
68 | #define __parse_rtattr_nested_compat(tb, max, rta, len) \ | 68 | #define __parse_rtattr_nested_compat(tb, max, rta, len) \ |
69 | ({if ((RTA_PAYLOAD(rta) >= len) && \ | 69 | ({ \ |
70 | (RTA_PAYLOAD(rta) >= RTA_ALIGN(len) + sizeof(struct rtattr))) { \ | 70 | if ((RTA_PAYLOAD(rta) >= len) \ |
71 | rta = RTA_DATA(rta) + RTA_ALIGN(len); \ | 71 | && (RTA_PAYLOAD(rta) >= RTA_ALIGN(len) + sizeof(struct rtattr)) \ |
72 | parse_rtattr_nested(tb, max, rta); \ | 72 | ) { \ |
73 | } else \ | 73 | rta = RTA_DATA(rta) + RTA_ALIGN(len); \ |
74 | memset(tb, 0, sizeof(struct rtattr *) * (max + 1)); \ | 74 | parse_rtattr_nested(tb, max, rta); \ |
75 | }) | 75 | } else \ |
76 | memset(tb, 0, sizeof(struct rtattr *) * (max + 1)); \ | ||
77 | }) | ||
76 | 78 | ||
77 | #define parse_rtattr_nested_compat(tb, max, rta, data, len) \ | 79 | #define parse_rtattr_nested_compat(tb, max, rta, data, len) \ |
78 | ({data = RTA_PAYLOAD(rta) >= len ? RTA_DATA(rta) : NULL; \ | 80 | ({ \ |
79 | __parse_rtattr_nested_compat(tb, max, rta, len); }) | 81 | data = RTA_PAYLOAD(rta) >= len ? RTA_DATA(rta) : NULL; \ |
82 | __parse_rtattr_nested_compat(tb, max, rta, len); \ | ||
83 | }) | ||
80 | 84 | ||
81 | #define show_details (0) /* not implemented. Does anyone need it? */ | 85 | #define show_details (0) /* not implemented. Does anyone need it? */ |
82 | #define use_iec (0) /* not currently documented in the upstream manpage */ | 86 | #define use_iec (0) /* not currently documented in the upstream manpage */ |