net: rpl: Neighbor data corrupted when receiving DAO message

The code was accessing wrong neighbor data when it received DAO
message. This corrupted nbr->iface pointer which was clearly seen
by "net nbr" shell command. The corruption then caused random
crashes or hangs when network interface via that pointer was
accessed.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
Jukka Rissanen 2017-09-19 09:52:38 +03:00
parent 9369538642
commit bc4ce8bda8

View file

@ -3336,7 +3336,7 @@ static enum net_verdict handle_dao(struct net_pkt *pkt)
struct net_rpl_dag *dag;
struct net_buf *frag;
struct in6_addr addr;
struct net_nbr *nbr;
struct net_nbr *ipv6_nbr, *rpl_nbr;
u16_t offset;
u16_t pos;
u8_t sequence;
@ -3502,9 +3502,9 @@ static enum net_verdict handle_dao(struct net_pkt *pkt)
NET_DBG("No-Path DAO received");
route = net_route_lookup(net_pkt_iface(pkt), &addr);
nbr = net_route_get_nbr(route);
if (nbr) {
extra = net_nbr_extra_data(nbr);
rpl_nbr = net_route_get_nbr(route);
if (rpl_nbr) {
extra = net_nbr_extra_data(rpl_nbr);
}
nexthop = net_route_get_nexthop(route);
@ -3542,17 +3542,17 @@ static enum net_verdict handle_dao(struct net_pkt *pkt)
return NET_DROP;
}
NET_DBG("Adding DAO route");
NET_DBG("Adding DAO route to %s", net_sprint_ipv6_addr(dao_sender));
nbr = net_ipv6_nbr_lookup(net_pkt_iface(pkt), dao_sender);
if (!nbr) {
nbr = net_ipv6_nbr_add(net_pkt_iface(pkt), dao_sender,
net_pkt_ll_src(pkt), false,
NET_IPV6_NBR_STATE_REACHABLE);
if (nbr) {
ipv6_nbr = net_ipv6_nbr_lookup(net_pkt_iface(pkt), dao_sender);
if (!ipv6_nbr) {
ipv6_nbr = net_ipv6_nbr_add(net_pkt_iface(pkt), dao_sender,
net_pkt_ll_src(pkt), false,
NET_IPV6_NBR_STATE_REACHABLE);
if (ipv6_nbr) {
/* Set reachable timer */
net_ipv6_nbr_set_reachable_timer(net_pkt_iface(pkt),
nbr);
ipv6_nbr);
NET_DBG("Neighbor %s [%s] added to neighbor cache",
net_sprint_ipv6_addr(dao_sender),
@ -3581,7 +3581,9 @@ static enum net_verdict handle_dao(struct net_pkt *pkt)
return NET_DROP;
}
extra = net_nbr_extra_data(nbr);
rpl_nbr = net_route_get_nbr(route);
extra = net_nbr_extra_data(rpl_nbr);
if (extra) {
extra->lifetime = net_rpl_lifetime(instance, lifetime);
extra->route_source = learned_from;