diff options
author | Denys Vlasenko | 2018-02-08 08:42:37 +0100 |
---|---|---|
committer | Denys Vlasenko | 2018-02-14 17:38:40 +0100 |
commit | f5b9a2267803bcb1dad5e902dcdfeefb65a112c3 (patch) | |
tree | cf523d028046012a1da3f7926435e776b438c59c | |
parent | 112392232028fa2ce215043e7f9cf78f7ff74afe (diff) | |
download | busybox-f5b9a2267803bcb1dad5e902dcdfeefb65a112c3.zip busybox-f5b9a2267803bcb1dad5e902dcdfeefb65a112c3.tar.gz |
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 921ecf0..d7f8881 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 1cd90d7..f572414 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 95dafe1..2a8610e 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 53b11e1..0ce0dfe 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 3f0f703..f08d862 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 be88a04..66401da 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 23abf63..284c930 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 */ |