]> git.puffer.fish Git - mirror/frr.git/commitdiff
isisd: fix use after free 10213/head
authorIgor Ryzhov <iryzhov@nfware.com>
Tue, 14 Dec 2021 13:28:08 +0000 (16:28 +0300)
committerIgor Ryzhov <iryzhov@nfware.com>
Tue, 14 Dec 2021 13:28:08 +0000 (16:28 +0300)
Pointers to the adjacency must be cleared only when the adjacency is
deleted. Otherwise, when the ISIS router is deleted later, the adjacency
is not deleted and a crash happens because of UAF.

Fixes #10209.

Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
isisd/isis_adjacency.c

index f5e8a790bfe64e1108b037f0c55369a12b52e951..9529adb09a59e51504569896ce8863e0d76cf0a0 100644 (file)
@@ -327,15 +327,18 @@ void isis_adj_state_change(struct isis_adjacency **padj,
                                adj->flaps++;
                        } else if (old_state == ISIS_ADJ_UP) {
                                circuit->adj_state_changes++;
-                               listnode_delete(circuit->u.bc.adjdb[level - 1],
-                                               adj);
 
                                circuit->upadjcount[level - 1]--;
                                if (circuit->upadjcount[level - 1] == 0)
                                        isis_tx_queue_clean(circuit->tx_queue);
 
-                               if (new_state == ISIS_ADJ_DOWN)
+                               if (new_state == ISIS_ADJ_DOWN) {
+                                       listnode_delete(
+                                               circuit->u.bc.adjdb[level - 1],
+                                               adj);
+
                                        del = true;
+                               }
                        }
 
                        if (circuit->u.bc.lan_neighs[level - 1]) {
@@ -374,14 +377,17 @@ void isis_adj_state_change(struct isis_adjacency **padj,
                                                         &circuit->t_send_csnp[1]);
                                }
                        } else if (old_state == ISIS_ADJ_UP) {
-                               if (adj->circuit->u.p2p.neighbor == adj)
-                                       adj->circuit->u.p2p.neighbor = NULL;
                                circuit->upadjcount[level - 1]--;
                                if (circuit->upadjcount[level - 1] == 0)
                                        isis_tx_queue_clean(circuit->tx_queue);
 
-                               if (new_state == ISIS_ADJ_DOWN)
+                               if (new_state == ISIS_ADJ_DOWN) {
+                                       if (adj->circuit->u.p2p.neighbor == adj)
+                                               adj->circuit->u.p2p.neighbor =
+                                                       NULL;
+
                                        del = true;
+                               }
                        }
                }
        }