summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Luong <sluong@cisco.com>2020-01-29 13:26:47 -0800
committerSteven Luong <sluong@cisco.com>2020-01-29 15:21:39 -0800
commitdfad26986077ff26b471c008a0fd77a79f767a3c (patch)
tree6d7a2aa22a465f3b947a2d4a869f4749d14e3ba7
parent0d40954b42519994b6b8ae1769d7a628d5f839fb (diff)
fib: refresh adj pointer after fib_walk_sync due to possible realloc
fib_walk_sync may call adj_alloc which may cause adj_pool to expand. When that happens, any previous frame which still use the old adj pointer needs to refresh. Failure to do so may access or update to the old adj memory unintentionally and crash mysteriously. Type: fix Ticket: VPPSUPP-54 Signed-off-by: Steven Luong <sluong@cisco.com> Change-Id: Ia7c6cb03c1ed9ddbbfb12dd42c8abc7f5b3f210c
-rw-r--r--src/vnet/adj/adj_nbr.c6
-rw-r--r--src/vnet/ethernet/arp.c14
2 files changed, 20 insertions, 0 deletions
diff --git a/src/vnet/adj/adj_nbr.c b/src/vnet/adj/adj_nbr.c
index c80317a67a5..758be3bfe9e 100644
--- a/src/vnet/adj/adj_nbr.c
+++ b/src/vnet/adj/adj_nbr.c
@@ -449,6 +449,12 @@ adj_nbr_update_rewrite_internal (ip_adjacency_t *adj,
};
fib_walk_sync(FIB_NODE_TYPE_ADJ, walk_ai, &bw_ctx);
+ /*
+ * fib_walk_sync may allocate a new adjacency and potentially cuase a realloc
+ * for adj_pool. When that happens, adj pointer is no longer valid here.
+ * We refresh the adj pointer accordingly.
+ */
+ adj = adj_get (ai);
}
/*
diff --git a/src/vnet/ethernet/arp.c b/src/vnet/ethernet/arp.c
index a42cfda0d3f..65de055d7d6 100644
--- a/src/vnet/ethernet/arp.c
+++ b/src/vnet/ethernet/arp.c
@@ -563,6 +563,13 @@ arp_update_adjacency (vnet_main_t * vnm, u32 sw_if_index, u32 ai)
* wouldn't be bad either, but that's more code than i'm prepared to
* write at this time for relatively little reward.
*/
+ /*
+ * adj_nbr_update_rewrite may actually call fib_walk_sync.
+ * fib_walk_sync may allocate a new adjacency and potentially cause
+ * a realloc for adj_pool. When that happens, adj pointer is no
+ * longer valid here. We refresh adj pointer accordingly.
+ */
+ adj = adj_get (ai);
arp_nbr_probe (adj);
}
break;
@@ -574,6 +581,13 @@ arp_update_adjacency (vnet_main_t * vnm, u32 sw_if_index, u32 ai)
sw_if_index,
VNET_LINK_IP4,
VNET_REWRITE_FOR_SW_INTERFACE_ADDRESS_BROADCAST));
+ /*
+ * Caution: adj_nbr_update_rewrite may actually call fib_walk_sync.
+ * fib_walk_sync may allocate a new adjacency and potentially cause a
+ * realloc for adj_pool. When that happens, adj pointer is no longer
+ * valid here. Please refresh adj pointer accordingly if it is still
+ * needed after the aformentioned call.
+ */
break;
case IP_LOOKUP_NEXT_MCAST:
{