summaryrefslogtreecommitdiffstats
path: root/isisd/isis_adjacency.c
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2020-04-18 02:06:07 +0200
committerDonald Sharp <sharpd@cumulusnetworks.com>2020-04-18 14:30:33 +0200
commit16167b31469c1cf3c6203495e639cbf640ef45f1 (patch)
treeedcdebd5b8d2835dc41b039b62c4cabefe986a76 /isisd/isis_adjacency.c
parentMerge pull request #6255 from mjstapp/fix_bitfield_free (diff)
downloadfrr-16167b31469c1cf3c6203495e639cbf640ef45f1.tar.xz
frr-16167b31469c1cf3c6203495e639cbf640ef45f1.zip
isisd: Prevent use after free for isis_adj_state_change
When we call isis_adj_state_change with ISIS_ADJ_DOWN we free the pointer, but we were still using the pointer after it was freed. Cleanup the api to prevent this. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Diffstat (limited to 'isisd/isis_adjacency.c')
-rw-r--r--isisd/isis_adjacency.c23
1 files changed, 11 insertions, 12 deletions
diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c
index 9beed206e..4e0ee4448 100644
--- a/isisd/isis_adjacency.c
+++ b/isisd/isis_adjacency.c
@@ -201,13 +201,14 @@ void isis_adj_process_threeway(struct isis_adjacency *adj,
fabricd_initial_sync_hello(adj->circuit);
if (next_tw_state == ISIS_THREEWAY_DOWN) {
- isis_adj_state_change(adj, ISIS_ADJ_DOWN, "Neighbor restarted");
+ isis_adj_state_change(&adj, ISIS_ADJ_DOWN,
+ "Neighbor restarted");
return;
}
if (next_tw_state == ISIS_THREEWAY_UP) {
if (adj->adj_state != ISIS_ADJ_UP) {
- isis_adj_state_change(adj, ISIS_ADJ_UP, NULL);
+ isis_adj_state_change(&adj, ISIS_ADJ_UP, NULL);
adj->adj_usage = adj_usage;
}
}
@@ -219,12 +220,13 @@ void isis_adj_process_threeway(struct isis_adjacency *adj,
adj->threeway_state = next_tw_state;
}
-void isis_adj_state_change(struct isis_adjacency *adj,
+void isis_adj_state_change(struct isis_adjacency **padj,
enum isis_adj_state new_state, const char *reason)
{
+ struct isis_adjacency *adj = *padj;
enum isis_adj_state old_state = adj->adj_state;
struct isis_circuit *circuit = adj->circuit;
- bool del;
+ bool del = false;
adj->adj_state = new_state;
if (new_state != old_state) {
@@ -262,7 +264,6 @@ void isis_adj_state_change(struct isis_adjacency *adj,
#endif /* ifndef FABRICD */
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
- del = false;
for (int level = IS_LEVEL_1; level <= IS_LEVEL_2; level++) {
if ((adj->level & level) == 0)
continue;
@@ -299,11 +300,7 @@ void isis_adj_state_change(struct isis_adjacency *adj,
lsp_regenerate_schedule_pseudo(circuit, level);
}
- if (del)
- isis_delete_adj(adj);
-
} else if (circuit->circ_type == CIRCUIT_T_P2P) {
- del = false;
for (int level = IS_LEVEL_1; level <= IS_LEVEL_2; level++) {
if ((adj->level & level) == 0)
continue;
@@ -336,9 +333,11 @@ void isis_adj_state_change(struct isis_adjacency *adj,
del = true;
}
}
+ }
- if (del)
- isis_delete_adj(adj);
+ if (del) {
+ isis_delete_adj(adj);
+ *padj = NULL;
}
}
@@ -402,7 +401,7 @@ int isis_adj_expire(struct thread *thread)
adj->t_expire = NULL;
/* trigger the adj expire event */
- isis_adj_state_change(adj, ISIS_ADJ_DOWN, "holding time expired");
+ isis_adj_state_change(&adj, ISIS_ADJ_DOWN, "holding time expired");
return 0;
}