Browse Source

isisd: Segmentation fault on isis daemon fixes

I have a fix for 2 segmentation fault scenarios on the isis daemon:
1. When running a command "isis passive" on an interface in the
following context:
"end"
"configure terminal "
"interface dummy0"
"isis passive"
The trace back collected:
isis_adjacency.c:521
family=2,
     root_sysid=0x20aee6d0 "", parent=0x20af4d68) at isis_spf.c:999
sysid=0x20aee6d0 "")
     at isis_spf.c:1217
isis_spf.c:1372
isis_lsp.c:416
isis_lsp.c:1660
isis_main.c:368

The fix location:
file name: isisd/isis_adjacency.c
routine name: isis_adj_build_up_list

2. When deleting the existing isis router instance:
"end"
"configure terminal "
"no router isis DEAD"

The fix location:
isisd/isis_events.c, routine circuit_resign_level
isisd/isis_lsp.c, routine lsp_destroy
isisd/isis_route.c, isis_route_validate

The trace back collection:
"DEAD") at isisd.c:252
argc=1, argv=0xbfc39054) at isisd.c:1520
vty=0x20d6f528, cmd=0x0) at command.c:2121
cmd=0x0, vtysh=0) at command.c:2155
isis DEAD") at vty.c:433
isis_main.c:368

and

"DEAD") at isisd.c:260
argc=1, argv=0xbfd6cf54) at isisd.c:1520
vty=0x208cb528, cmd=0x0) at command.c:2121
cmd=0x0, vtysh=0) at command.c:2155
isis DEAD") at vty.c:433
isis_main.c:368

The patch is included.

patchwork #833: http://patchwork.quagga.net/patch/833/
boris yakubov 6 years ago
parent
commit
a0a661f982
4 changed files with 22 additions and 10 deletions
  1. 5 0
      isisd/isis_adjacency.c
  2. 4 2
      isisd/isis_events.c
  3. 10 8
      isisd/isis_lsp.c
  4. 3 0
      isisd/isis_route.c

+ 5 - 0
isisd/isis_adjacency.c

@@ -507,6 +507,11 @@ isis_adj_build_up_list (struct list *adjdb, struct list *list)
   struct isis_adjacency *adj;
   struct listnode *node;
 
+  if (adjdb == NULL) {
+    zlog_warn ("isis_adj_build_up_list(): adjacency DB is empty");
+    return;
+  }
+
   if (!list)
     {
       zlog_warn ("isis_adj_build_up_list(): NULL list");

+ 4 - 2
isisd/isis_events.c

@@ -250,8 +250,10 @@ circuit_resign_level (struct isis_circuit *circuit, int level)
       THREAD_TIMER_OFF (circuit->u.bc.t_refresh_pseudo_lsp[idx]);
       circuit->lsp_regenerate_pending[idx] = 0;
       circuit->u.bc.run_dr_elect[idx] = 0;
-      list_delete (circuit->u.bc.lan_neighs[idx]);
-      circuit->u.bc.lan_neighs[idx] = NULL;
+      if (circuit->u.bc.lan_neighs[idx] != NULL) {
+        list_delete (circuit->u.bc.lan_neighs[idx]);
+        circuit->u.bc.lan_neighs[idx] = NULL;
+      }
     }
 
   return;

+ 10 - 8
isisd/isis_lsp.c

@@ -137,14 +137,16 @@ lsp_destroy (struct isis_lsp *lsp)
   if (!lsp)
     return;
 
-  for (ALL_LIST_ELEMENTS_RO (lsp->area->circuit_list, cnode, circuit))
-    {
-      if (circuit->lsp_queue == NULL)
-        continue;
-      for (ALL_LIST_ELEMENTS (circuit->lsp_queue, lnode, lnnode, lsp_in_list))
-        if (lsp_in_list == lsp)
-          list_delete_node(circuit->lsp_queue, lnode);
-    }
+  if (lsp->area->circuit_list) {
+    for (ALL_LIST_ELEMENTS_RO (lsp->area->circuit_list, cnode, circuit))
+      {
+        if (circuit->lsp_queue == NULL)
+          continue;
+        for (ALL_LIST_ELEMENTS (circuit->lsp_queue, lnode, lnnode, lsp_in_list))
+          if (lsp_in_list == lsp)
+            list_delete_node(circuit->lsp_queue, lnode);
+      }
+  }
   ISIS_FLAGS_CLEAR_ALL (lsp->SSNflags);
   ISIS_FLAGS_CLEAR_ALL (lsp->SRMflags);
 

+ 3 - 0
isisd/isis_route.c

@@ -643,6 +643,9 @@ isis_route_validate (struct isis_area *area)
     isis_route_validate_merge (area, AF_INET6);
 #endif
 
+  if (!area->circuit_list) {
+    return;
+  }
   /* walk all circuits and reset any spf specific flags */
   for (ALL_LIST_ELEMENTS_RO (area->circuit_list, node, circuit))
     UNSET_FLAG(circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF);