From 5cb904b57e0cbcb84ffdf036ab3ad37ad7431ad3 Mon Sep 17 00:00:00 2001 From: Yonezawa-T2 Date: Wed, 9 Dec 2015 14:28:51 +0900 Subject: [PATCH 1/4] gnrc_sixlowpan_nd: fixed crash on gnrc_sixlowpan_nd_next_hop_l2addr. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When `gnrc_ndp_node_next_hop_l2addr` cannot resolve L2 address, it creates a temporary neighbor cache entry with interface `KERNEL_PID_UNDEF` (unless the interface is already known) to send a neighbor solicitation. When another packet directed to the same address is going to sent before receiving a neighbor advertisement, `gnrc_sixlowpan_nd_next_hop_l2addr` gets the temporary neighbor cache entry and calls `gnrc_ipv6_netif_get` with `KERNEL_PID_UNDEF`, resulting get a `NULL`. We must check `NULL` before dereference it. FYI, both `gnrc_ndp_node_next_hop_l2addr` and `gnrc_sixlowpan_nd_next_hop_l2addr` are enabled when `gnrc_sixlowpan_border_router_default` module is enabled with `GNRC_NETIF_NUMOF` is greater than 1: gnrc_sixlowpan_border_router_default → gnrc_ipv6_router_default → gnrc_ndp_router (if GNRC_NETIF_NUMOF > 1) → gnrc_ndp_node → gnrc_ndp_node_next_hop_l2addr is called from _next_hop_l2addr gnrc_sixlowpan_border_router_default → gnrc_sixlowpan_nd_border_router → gnrc_sixlowpan_nd_router → gnrc_sixlowpan_nd → gnrc_sixlowpan_nd_next_hop_l2addr is called from _next_hop_l2addr --- .../gnrc/network_layer/sixlowpan/nd/gnrc_sixlowpan_nd.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sys/net/gnrc/network_layer/sixlowpan/nd/gnrc_sixlowpan_nd.c b/sys/net/gnrc/network_layer/sixlowpan/nd/gnrc_sixlowpan_nd.c index 90b2bbd9c082..ebd9cfcd5e83 100644 --- a/sys/net/gnrc/network_layer/sixlowpan/nd/gnrc_sixlowpan_nd.c +++ b/sys/net/gnrc/network_layer/sixlowpan/nd/gnrc_sixlowpan_nd.c @@ -154,10 +154,11 @@ kernel_pid_t gnrc_sixlowpan_nd_next_hop_l2addr(uint8_t *l2addr, uint8_t *l2addr_ if (nc_entry != NULL) { gnrc_ipv6_netif_t *ipv6_if = gnrc_ipv6_netif_get(nc_entry->iface); /* and interface is not 6LoWPAN */ - if (!(ipv6_if->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) || + if (!((ipv6_if == NULL) || + (ipv6_if->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN)) || /* or entry is registered */ - (gnrc_ipv6_nc_get_type(nc_entry) == GNRC_IPV6_NC_TYPE_REGISTERED)) { - next_hop = dst; + (gnrc_ipv6_nc_get_type(nc_entry) == GNRC_IPV6_NC_TYPE_REGISTERED)) { + next_hop = dst; } } #endif From 542e045bba614e5081e2802b17529a1fa227dd7f Mon Sep 17 00:00:00 2001 From: Yonezawa-T2 Date: Tue, 8 Dec 2015 19:20:59 +0900 Subject: [PATCH 2/4] gnrc_ipv6_netif: fixed crash when ENABLE_DEBUG is 1. When ENABLE_DEBUG is 1, `out` is dereferenced unconditionally, but `_parse_options` in `gnrc_rpl_control_messages.c` calls it with NULL. Clarified `out` must not NULL and fixed `_parse_options`. --- sys/include/net/gnrc/ipv6/netif.h | 2 ++ sys/net/gnrc/network_layer/ipv6/netif/gnrc_ipv6_netif.c | 5 +---- sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c | 3 ++- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sys/include/net/gnrc/ipv6/netif.h b/sys/include/net/gnrc/ipv6/netif.h index 3385003f90a5..637a563dd469 100644 --- a/sys/include/net/gnrc/ipv6/netif.h +++ b/sys/include/net/gnrc/ipv6/netif.h @@ -484,6 +484,8 @@ ipv6_addr_t *gnrc_ipv6_netif_find_addr(kernel_pid_t pid, const ipv6_addr_t *addr * * @param[in] prefix The prefix you want to search for. * + * @pre @p out must not be NULL. + * * @return The PID to the interface the address is registered to. * @return KERNEL_PID_UNDEF, if no matching address can not be found on any * interface. diff --git a/sys/net/gnrc/network_layer/ipv6/netif/gnrc_ipv6_netif.c b/sys/net/gnrc/network_layer/ipv6/netif/gnrc_ipv6_netif.c index 1fbcc47e8c3e..e927b21a448a 100644 --- a/sys/net/gnrc/network_layer/ipv6/netif/gnrc_ipv6_netif.c +++ b/sys/net/gnrc/network_layer/ipv6/netif/gnrc_ipv6_netif.c @@ -502,10 +502,7 @@ kernel_pid_t gnrc_ipv6_netif_find_by_prefix(ipv6_addr_t **out, const ipv6_addr_t match = _find_by_prefix_unsafe(&tmp_res, ipv6_ifs + i, prefix, NULL); if (match > best_match) { - if (out != NULL) { - *out = tmp_res; - } - + *out = tmp_res; res = ipv6_ifs[i].pid; best_match = match; } diff --git a/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c b/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c index 297ec132c92e..39eefa25be55 100644 --- a/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c +++ b/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c @@ -430,7 +430,8 @@ bool _parse_options(int msg_type, gnrc_rpl_instance_t *inst, gnrc_rpl_opt_t *opt case (GNRC_RPL_OPT_TARGET): DEBUG("RPL: RPL TARGET DAO option parsed\n"); *included_opts |= ((uint32_t) 1) << GNRC_RPL_OPT_TARGET; - if_id = gnrc_ipv6_netif_find_by_prefix(NULL, &dodag->dodag_id); + ipv6_addr_t *prefix = NULL; + if_id = gnrc_ipv6_netif_find_by_prefix(&prefix, &dodag->dodag_id); if (if_id == KERNEL_PID_UNDEF) { DEBUG("RPL: no interface found for the configured DODAG id\n"); return false; From c9c83c7dc7a970ae342d0a461c9e8f9e19fca5a9 Mon Sep 17 00:00:00 2001 From: Yonezawa-T2 Date: Tue, 8 Dec 2015 19:24:35 +0900 Subject: [PATCH 3/4] nc: cancel timer set by `gnrc_ndp_rtr_sol_handle` in `gnrc_ipv6_nc_remove`. --- sys/net/gnrc/network_layer/ipv6/nc/gnrc_ipv6_nc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sys/net/gnrc/network_layer/ipv6/nc/gnrc_ipv6_nc.c b/sys/net/gnrc/network_layer/ipv6/nc/gnrc_ipv6_nc.c index 590c34616480..8357b9924bc4 100644 --- a/sys/net/gnrc/network_layer/ipv6/nc/gnrc_ipv6_nc.c +++ b/sys/net/gnrc/network_layer/ipv6/nc/gnrc_ipv6_nc.c @@ -163,6 +163,13 @@ void gnrc_ipv6_nc_remove(kernel_pid_t iface, const ipv6_addr_t *ipv6_addr) #endif #ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER xtimer_remove(&entry->type_timeout); + + gnrc_ipv6_netif_t *if_entry = gnrc_ipv6_netif_get(iface); + + if ((if_entry != NULL) && (if_entry->rtr_adv_msg.content.ptr == (char *) entry)) { + /* cancel timer set by gnrc_ndp_rtr_sol_handle */ + xtimer_remove(&if_entry->rtr_adv_timer); + } #endif #if defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER) xtimer_remove(&entry->rtr_adv_timer); From cf35763584380dd697b7c403055d230af8915b76 Mon Sep 17 00:00:00 2001 From: Yonezawa-T2 Date: Tue, 8 Dec 2015 20:29:01 +0900 Subject: [PATCH 4/4] fib: add debug outputs --- sys/net/network_layer/fib/fib.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/sys/net/network_layer/fib/fib.c b/sys/net/network_layer/fib/fib.c index bc6533ac9c76..b9cf05ce5598 100644 --- a/sys/net/network_layer/fib/fib.c +++ b/sys/net/network_layer/fib/fib.c @@ -88,6 +88,14 @@ static int fib_find_entry(fib_table_t *table, uint8_t *dst, size_t dst_size, int ret = -EHOSTUNREACH; bool is_all_zeros_addr = true; +#if ENABLE_DEBUG + DEBUG("[fib_find_entry] dst ="); + for (size_t i = 0; i < dst_size; i++) { + DEBUG(" %02x", dst[i]); + } + DEBUG("\n"); +#endif + for (size_t i = 0; i < dst_size; ++i) { if (dst[i] != 0) { is_all_zeros_addr = false; @@ -125,6 +133,7 @@ static int fib_find_entry(fib_table_t *table, uint8_t *dst, size_t dst_size, int ret_comp = universal_address_compare(table->data.entries[i].global, dst, &match_size); /* If we found an exact match */ if (ret_comp == 0 || (is_all_zeros_addr && match_size == 0)) { + DEBUG("[fib_find_entry] found an exact match"); entry_arr[0] = &(table->data.entries[i]); *entry_arr_size = 1; /* we will not find a better one so we return */ @@ -148,6 +157,16 @@ static int fib_find_entry(fib_table_t *table, uint8_t *dst, size_t dst_size, } } +#if ENABLE_DEBUG + if (count > 0) { + DEBUG("[fib_find_entry] found prefix on interface %d:", entry_arr[0]->iface_id); + for (size_t i = 0; i < entry_arr[0]->global->address_size; i++) { + DEBUG(" %02x", entry_arr[0]->global->address[i]); + } + DEBUG("\n"); + } +#endif + *entry_arr_size = count; return ret; }