ip: fix crash in "ip neigh show"
authorDenys Vlasenko <vda.linux@googlemail.com>
Thu, 8 Feb 2018 07:42:37 +0000 (08:42 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Wed, 14 Feb 2018 16:38:40 +0000 (17:38 +0100)
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>
networking/libiproute/ipaddress.c
networking/libiproute/ipneigh.c
networking/libiproute/iproute.c
networking/libiproute/iprule.c
networking/libiproute/libnetlink.c
networking/libiproute/ll_map.c
networking/tc.c

index 921ecf0d943864e4873239b992d9ba1e6782c822..d7f8881766368c301b9ad6c4b12efe72532d5fc8 100644 (file)
@@ -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];
index 1cd90d707c3aed18de16fc3d8416f6b24815a5c3..f572414e9ace3ac1c0ee858773a14966d838c572 100644 (file)
@@ -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)));
 
index 95dafe18320f7c6de932983d14e9ba6c9cada78a..2a8610ea66376f3d864c6b0f40121d6918ea42d3 100644 (file)
@@ -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]) {
index 53b11e16c36fded6dc3e61e9dbff754ca983247e..0ce0dfeef6685a0498c41f23fa7386dce0c40eef 100644 (file)
@@ -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)
index 3f0f7032633d733774245e3d07b48ea298e1695a..f08d862d0589993b541386a637ea4b97077354eb 100644 (file)
@@ -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;
index be88a04e88e2812d31af7d1fd3f05c39af9b1083..66401da77fac47ac8172e7bc5a6ca871856c00e7 100644 (file)
@@ -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;
index 23abf636ce3145bb0b198faaa4596bfec31b9636..284c9309852333abaf9811508b6c41fc454be2f9 100644 (file)
 
 /* 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 */