From cab7be7d5b1dfe6badb35160dd84bc9a10d33aa2 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Fri, 27 May 2022 10:37:08 +0200 Subject: [PATCH 1/2] Revert "isisd: fix infinite loop when parsing LSPs" This reverts commit 5e56a50559fd4a85f1912464e6e13d13969aa238. --- isisd/isis_spf.c | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index 09f92554c0..2d792a9c75 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -1400,13 +1400,14 @@ static void spf_adj_list_parse_tlv(struct isis_spftree *spftree, spf_adj_list_parse_lsp(spftree, adj_list, lsp, id, metric); } -static void spf_adj_list_parse_lsp_frag(struct isis_spftree *spftree, - struct list *adj_list, - struct isis_lsp *lsp, - const uint8_t *pseudo_nodeid, - uint32_t pseudo_metric) +static void spf_adj_list_parse_lsp(struct isis_spftree *spftree, + struct list *adj_list, struct isis_lsp *lsp, + const uint8_t *pseudo_nodeid, + uint32_t pseudo_metric) { bool pseudo_lsp = LSP_PSEUDO_ID(lsp->hdr.lsp_id); + struct isis_lsp *frag; + struct listnode *node; struct isis_item *head; struct isis_item_list *te_neighs; @@ -1444,27 +1445,14 @@ static void spf_adj_list_parse_lsp_frag(struct isis_spftree *spftree, } } } -} - - -static void spf_adj_list_parse_lsp(struct isis_spftree *spftree, - struct list *adj_list, struct isis_lsp *lsp, - const uint8_t *pseudo_nodeid, - uint32_t pseudo_metric) -{ - struct isis_lsp *frag; - struct listnode *node; - - spf_adj_list_parse_lsp_frag(spftree, adj_list, lsp, pseudo_nodeid, - pseudo_metric); /* Parse LSP fragments. */ for (ALL_LIST_ELEMENTS_RO(lsp->lspu.frags, node, frag)) { if (!frag->tlvs) continue; - spf_adj_list_parse_lsp_frag(spftree, adj_list, frag, - pseudo_nodeid, pseudo_metric); + spf_adj_list_parse_lsp(spftree, adj_list, frag, pseudo_nodeid, + pseudo_metric); } } From 8c8a5a02fa66523a96142083575e1eb7b0033667 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Fri, 27 May 2022 10:42:53 +0200 Subject: [PATCH 2/2] isisd: fix infinite loop when parsing LSPs Fixing the crash: > #0 0x0000560aa80f8e30 in lspdb_const_find (h=, item=) at ./isisd/isis_lsp.h:64 > #1 0x0000560aa80f8e9d in lspdb_find (h=0x560aaa1ed3b8, item=0x7fff5e95f050) at ./isisd/isis_lsp.h:64 > #2 0x0000560aa80f92f9 in lsp_search (head=0x560aaa1ed3b8, id=0x7fff5e95f200 "") at isisd/isis_lsp.c:100 > #3 0x0000560aa8113d69 in spf_adj_list_parse_tlv (spftree=0x560aaa1f09d0, adj_list=0x560aaa214480, id=0x560aad331a78 "", desig_is_id=0x0, pseudo_metric=0, metric=3, oldmetric=false, subtlvs=0x0) at isisd/isis_spf.c:1330 > #4 0x0000560aa811419d in spf_adj_list_parse_lsp (spftree=0x560aaa1f09d0, adj_list=0x560aaa214480, lsp=0x560aaa1f4e50, pseudo_nodeid=0x0, pseudo_metric=0) at isisd/isis_spf.c:1429 > #5 0x0000560aa81141fe in spf_adj_list_parse_lsp (spftree=0x560aaa1f09d0, adj_list=0x560aaa214480, lsp=0x560aaa1ff8e0, pseudo_nodeid=0x0, pseudo_metric=0) at isisd/isis_spf.c:1442 > #6 0x0000560aa81141fe in spf_adj_list_parse_lsp (spftree=0x560aaa1f09d0, adj_list=0x560aaa214480, lsp=0x560aaa1f4e50, pseudo_nodeid=0x0, pseudo_metric=0) at isisd/isis_spf.c:1442 > (...) > #65507 0x0000560aa81141fe in spf_adj_list_parse_lsp (spftree=0x560aaa1f09d0, adj_list=0x560aaa214480, lsp=0x560aaa1ff8e0, pseudo_nodeid=0x0, pseudo_metric=0) at isisd/isis_spf.c:1442 > #65508 0x0000560aa81141fe in spf_adj_list_parse_lsp (spftree=0x560aaa1f09d0, adj_list=0x560aaa214480, lsp=0x560aaa1f4e50, pseudo_nodeid=0x0, pseudo_metric=0) at isisd/isis_spf.c:1442 > #65509 0x0000560aa81141fe in spf_adj_list_parse_lsp (spftree=0x560aaa1f09d0, adj_list=0x560aaa214480, lsp=0x560aaa1ff8e0, pseudo_nodeid=0x0, pseudo_metric=0) at isisd/isis_spf.c:1442 > #65510 0x0000560aa81141fe in spf_adj_list_parse_lsp (spftree=0x560aaa1f09d0, adj_list=0x560aaa214480, lsp=0x560aaa1f4e50, pseudo_nodeid=0x0, pseudo_metric=0) at isisd/isis_spf.c:1442 > #65511 0x0000560aa8114313 in isis_spf_build_adj_list (spftree=0x560aaa1f09d0, lsp=0x560aaa1f4e50) at isisd/isis_spf.c:1455 > #65512 0x0000560aa8114f09 in isis_run_spf (spftree=0x560aaa1f09d0) at isisd/isis_spf.c:1775 > #65513 0x0000560aa8115057 in isis_run_spf_with_protection (area=0x560aaa1ed3b0, spftree=0x560aaa1f09d0) at isisd/isis_spf.c:1801 > #65514 0x0000560aa8115311 in isis_run_spf_cb (thread=0x7fff5f15e5a0) at isisd/isis_spf.c:1859 > #65515 0x00007f90bac66dcc in thread_call (thread=0x7fff5f15e5a0) at lib/thread.c:2002 > #65516 0x00007f90bac013ee in frr_run (master=0x560aa9f5cb40) at lib/libfrr.c:1196 > #65517 0x0000560aa80e7da2 in main (argc=2, argv=0x7fff5f15e7b8, envp=0x7fff5f15e7d0) at isisd/isis_main.c:273 The fix is similar to the crash fix included in d9884a758c ("isisd: Prepare IS-IS for Link State support"). The fix was: > diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c > index 94353a5bc8..92d329f035 100644 > --- a/isisd/isis_lsp.c > +++ b/isisd/isis_lsp.c > @@ -2166,7 +2178,7 @@ int isis_lsp_iterate_ip_reach(struct isis_lsp *lsp, int family, uint16_t mtid, > if (lsp->hdr.seqno == 0 || lsp->hdr.rem_lifetime == 0) > return LSP_ITER_CONTINUE; > > - /* Parse main LSP. */ > + /* Parse LSP */ > if (lsp->tlvs) { > if (!fabricd && !pseudo_lsp && family == AF_INET > && mtid == ISIS_MT_IPV4_UNICAST) { > @@ -2236,13 +2248,17 @@ int isis_lsp_iterate_ip_reach(struct isis_lsp *lsp, int family, uint16_t mtid, > } > } > > - /* Parse LSP fragments. */ > - for (ALL_LIST_ELEMENTS_RO(lsp->lspu.frags, node, frag)) { > - if (!frag->tlvs) > - continue; > + /* Parse LSP fragments if it is not a fragment itself */ > + if (!LSP_FRAGMENT(lsp->hdr.lsp_id)) > + for (ALL_LIST_ELEMENTS_RO(lsp->lspu.frags, node, frag)) { > + if (!frag->tlvs) > + continue; > > - isis_lsp_iterate_ip_reach(frag, family, mtid, cb, arg); > - } > + if (isis_lsp_iterate_ip_reach(frag, family, mtid, cb, > + arg) > + == LSP_ITER_STOP) > + return LSP_ITER_STOP; > + } > > return LSP_ITER_CONTINUE; > } Fixes: 7b36d36e0e ("isisd: make the SPF code more modular") Fixes: 5e56a50559 ("isisd: fix infinite loop when parsing LSPs") Signed-off-by: Louis Scalbert --- isisd/isis_spf.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index 2d792a9c75..3aef8ada24 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -1414,7 +1414,7 @@ static void spf_adj_list_parse_lsp(struct isis_spftree *spftree, if (lsp->hdr.seqno == 0 || lsp->hdr.rem_lifetime == 0) return; - /* Parse main LSP. */ + /* Parse LSP. */ if (lsp->tlvs) { if (pseudo_lsp || spftree->mtid == ISIS_MT_IPV4_UNICAST) { head = lsp->tlvs->oldstyle_reach.head; @@ -1446,6 +1446,9 @@ static void spf_adj_list_parse_lsp(struct isis_spftree *spftree, } } + if (LSP_FRAGMENT(lsp->hdr.lsp_id)) + return; + /* Parse LSP fragments. */ for (ALL_LIST_ELEMENTS_RO(lsp->lspu.frags, node, frag)) { if (!frag->tlvs)