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>
This commit is contained in:
parent
237a900bc5
commit
68ae54243c
@ -113,7 +113,7 @@ static NOINLINE int print_linkinfo(const struct nlmsghdr *n)
|
|||||||
if (G_filter.up && !(ifi->ifi_flags & IFF_UP))
|
if (G_filter.up && !(ifi->ifi_flags & IFF_UP))
|
||||||
return 0;
|
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);
|
parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
|
||||||
if (tb[IFLA_IFNAME] == NULL) {
|
if (tb[IFLA_IFNAME] == NULL) {
|
||||||
bb_error_msg("nil ifname");
|
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)
|
if (G_filter.flushb && n->nlmsg_type != RTM_NEWADDR)
|
||||||
return 0;
|
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)));
|
parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa)));
|
||||||
|
|
||||||
if (!rta_tb[IFA_LOCAL])
|
if (!rta_tb[IFA_LOCAL])
|
||||||
@ -535,7 +535,7 @@ int FAST_FUNC ipaddr_list_or_flush(char **argv, int flush)
|
|||||||
continue;
|
continue;
|
||||||
if (G_filter.pfx.family || G_filter.label) {
|
if (G_filter.pfx.family || G_filter.label) {
|
||||||
struct rtattr *tb[IFA_MAX+1];
|
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));
|
parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), IFA_PAYLOAD(n));
|
||||||
if (!tb[IFA_LOCAL])
|
if (!tb[IFA_LOCAL])
|
||||||
tb[IFA_LOCAL] = tb[IFA_ADDRESS];
|
tb[IFA_LOCAL] = tb[IFA_ADDRESS];
|
||||||
|
@ -110,11 +110,13 @@ static int FAST_FUNC print_neigh(const struct sockaddr_nl *who UNUSED_PARAM,
|
|||||||
return 0;
|
return 0;
|
||||||
if (G_filter.index && G_filter.index != r->ndm_ifindex)
|
if (G_filter.index && G_filter.index != r->ndm_ifindex)
|
||||||
return 0;
|
return 0;
|
||||||
if (!(G_filter.state&r->ndm_state) &&
|
if (!(G_filter.state&r->ndm_state)
|
||||||
!(r->ndm_flags & NTF_PROXY) &&
|
&& !(r->ndm_flags & NTF_PROXY)
|
||||||
(r->ndm_state || !(G_filter.state & 0x100)) &&
|
&& (r->ndm_state || !(G_filter.state & 0x100))
|
||||||
(r->ndm_family != AF_DECnet))
|
&& (r->ndm_family != AF_DECnet)
|
||||||
|
) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
parse_rtattr(tb, NDA_MAX, NDA_RTA(r), n->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
|
parse_rtattr(tb, NDA_MAX, NDA_RTA(r), n->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM,
|
|||||||
if (len < 0)
|
if (len < 0)
|
||||||
bb_error_msg_and_die("wrong nlmsg len %d", len);
|
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);
|
parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
|
||||||
|
|
||||||
#if HAVE_RTA_TABLE
|
#if HAVE_RTA_TABLE
|
||||||
@ -1081,7 +1081,7 @@ static int iproute_get(char **argv)
|
|||||||
bb_error_msg_and_die("wrong len %d", len);
|
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);
|
parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
|
||||||
|
|
||||||
if (tb[RTA_PREFSRC]) {
|
if (tb[RTA_PREFSRC]) {
|
||||||
|
@ -63,7 +63,7 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM,
|
|||||||
if (len < 0)
|
if (len < 0)
|
||||||
return -1;
|
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);
|
parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
|
||||||
|
|
||||||
if (r->rtm_family == AF_INET)
|
if (r->rtm_family == AF_INET)
|
||||||
|
@ -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)
|
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)) {
|
while (RTA_OK(rta, len)) {
|
||||||
if (rta->rta_type <= max) {
|
if (rta->rta_type <= max) {
|
||||||
tb[rta->rta_type] = rta;
|
tb[rta->rta_type] = rta;
|
||||||
|
@ -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)))
|
if (n->nlmsg_len < NLMSG_LENGTH(sizeof(ifi)))
|
||||||
return -1;
|
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));
|
parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), IFLA_PAYLOAD(n));
|
||||||
if (tb[IFLA_IFNAME] == NULL)
|
if (tb[IFLA_IFNAME] == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -66,17 +66,21 @@ enum
|
|||||||
|
|
||||||
/* nullifies tb on error */
|
/* nullifies tb on error */
|
||||||
#define __parse_rtattr_nested_compat(tb, max, rta, len) \
|
#define __parse_rtattr_nested_compat(tb, max, rta, len) \
|
||||||
({if ((RTA_PAYLOAD(rta) >= len) && \
|
({ \
|
||||||
(RTA_PAYLOAD(rta) >= RTA_ALIGN(len) + sizeof(struct rtattr))) { \
|
if ((RTA_PAYLOAD(rta) >= len) \
|
||||||
rta = RTA_DATA(rta) + RTA_ALIGN(len); \
|
&& (RTA_PAYLOAD(rta) >= RTA_ALIGN(len) + sizeof(struct rtattr)) \
|
||||||
parse_rtattr_nested(tb, max, rta); \
|
) { \
|
||||||
} else \
|
rta = RTA_DATA(rta) + RTA_ALIGN(len); \
|
||||||
memset(tb, 0, sizeof(struct rtattr *) * (max + 1)); \
|
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) \
|
#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 show_details (0) /* not implemented. Does anyone need it? */
|
||||||
#define use_iec (0) /* not currently documented in the upstream manpage */
|
#define use_iec (0) /* not currently documented in the upstream manpage */
|
||||||
|
Loading…
Reference in New Issue
Block a user