aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Luong <sluong@cisco.com>2020-01-30 09:11:18 -0800
committersteven luong <sluong@cisco.com>2020-02-03 15:06:38 +0000
commit1934b13d3673ec1f86a025ed6094a9d5c0790170 (patch)
tree2105c6f748a567673c6547e5b665b5c0ea860db9
parentfce396738f865293f0a023bc7f172086f81da456 (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: I173dec4c5ce81c6e26c4fe011b894a7345901b24 (cherry picked from commit 3d5f6229bccf77fcf7e0e17ab4f1b361fedd1b2b)
-rw-r--r--src/vnet/adj/adj_nbr.c6
-rw-r--r--src/vnet/ip-neighbor/ip_neighbor.c7
2 files changed, 13 insertions, 0 deletions
diff --git a/src/vnet/adj/adj_nbr.c b/src/vnet/adj/adj_nbr.c
index 9e990e00f3b..a8b92e90096 100644
--- a/src/vnet/adj/adj_nbr.c
+++ b/src/vnet/adj/adj_nbr.c
@@ -452,6 +452,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/ip-neighbor/ip_neighbor.c b/src/vnet/ip-neighbor/ip_neighbor.c
index d8c386dd527..6af76d262a4 100644
--- a/src/vnet/ip-neighbor/ip_neighbor.c
+++ b/src/vnet/ip-neighbor/ip_neighbor.c
@@ -615,6 +615,13 @@ ip_neighbor_update (vnet_main_t * vnm, adj_index_t 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.x We refresh adj pointer accordingly.
+ */
+ adj = adj_get (ai);
ip_neighbor_probe (adj);
}
break;