]> git.puffer.fish Git - matthieu/frr.git/commitdiff
isisd: fix use after free
authorIgor Ryzhov <iryzhov@nfware.com>
Tue, 14 Dec 2021 13:28:08 +0000 (16:28 +0300)
committermergify-bot <noreply@mergify.com>
Thu, 16 Dec 2021 14:42:33 +0000 (14:42 +0000)
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>
(cherry picked from commit 7209d2a4cca79fc823b65cc5854f06debb2ac448)

isisd/isis_adjacency.c

index ffda0f8643bc5932d8d12874ade83a61bac6ccc6..20489cb7dcb40cb5140c989e62358670f0601ff3 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;
+                               }
                        }
                }
        }