Go to file
zhou-run f727c63790 isisd: fix crash when calculating the neighbor spanning tree based on the fragmented LSP
1. When the root IS regenerates an LSP, it calls lsp_build() -> lsp_clear_data() to free the TLV memory of the first fragment and all other fragments. If the number of fragments in the regenerated LSP decreases or if no fragmentation is needed, the extra LSP fragments are not immediately deleted. Instead, lsp_seqno_update() -> lsp_purge() is called to set the remaining time to zero and start aging, while also notifying other IS nodes to age these fragments. lsp_purge() usually does not reset lsp->hdr.seqno to zero because the LSP might recover during the aging process.
2. When other IS nodes receive an LSP, they always call process_lsp() -> isis_unpack_tlvs() to allocate TLV memory for the LSP. This does not differentiate whether the received LSP has a remaining lifetime of zero. Therefore, it is rare for an LSP of a non-root IS to have empty TLVs. Of course, if an LSP with a remaining time of zero and already corrupted is received, lsp_update() -> lsp_purge() will be called to free the TLV memory of the LSP, but this scenario is rare.
3. In LFA calculations, neighbors of the root IS are traversed, and each neighbor is taken as a new root to compute the neighbor SPT. During this process, the old root IS will serve as a neighbor of the new root IS, triggering a call to isis_spf_process_lsp() to parse the LSP of the old root IS and obtain its IP vertices and neighboring IS vertices. However, isis_spf_process_lsp() only checks whether the TLVs in the first fragment of the LSP exist, and does not check the TLVs in the fragmented LSP. If the TLV memory of the fragmented LSP of the old root IS has been freed, it can lead to a null pointer access, causing the current crash.

Additionally, for the base SPT, there are only two places where the LSP of the root IS is parsed:
1. When obtaining the UP neighbors of the root IS via spf_adj_list_parse_lsp().
2. When preloading the IP vertices of the root IS via isis_lsp_iterate_ip_reach().
Both of these checks ensure that frag->tlvs is not null, and they do not subsequently call isis_spf_process_lsp() to parse the root IS's LSP. It is very rare for non-root IS LSPs to have empty TLVs unless they are corrupted LSPs awaiting deletion. If it happens, a crash will occur.

The backtrace is as follows:
(gdb) bt
#0  0x00007f3097281fe1 in raise () from /lib/x86_64-linux-gnu/libpthread.so.0
#1  0x00007f30973a2972 in core_handler (signo=11, siginfo=0x7ffce66c2870, context=0x7ffce66c2740) at ../lib/sigevent.c:261
#2  <signal handler called>
#3  0x000055dfa805512b in isis_spf_process_lsp (spftree=0x55dfa950eee0, lsp=0x55dfa94cb590, cost=10, depth=1, root_sysid=0x55dfa950ef6c "", parent=0x55dfa952fca0)
    at ../isisd/isis_spf.c:898
#4  0x000055dfa805743b in isis_spf_loop (spftree=0x55dfa950eee0, root_sysid=0x55dfa950ef6c "") at ../isisd/isis_spf.c:1688
#5  0x000055dfa805784f in isis_run_spf (spftree=0x55dfa950eee0) at ../isisd/isis_spf.c:1808
#6  0x000055dfa8037ff5 in isis_spf_run_neighbors (spftree=0x55dfa9474440) at ../isisd/isis_lfa.c:1259
#7  0x000055dfa803ac17 in isis_spf_run_lfa (area=0x55dfa9477510, spftree=0x55dfa9474440) at ../isisd/isis_lfa.c:2300
#8  0x000055dfa8057964 in isis_run_spf_with_protection (area=0x55dfa9477510, spftree=0x55dfa9474440) at ../isisd/isis_spf.c:1827
#9  0x000055dfa8057c15 in isis_run_spf_cb (thread=0x7ffce66c38e0) at ../isisd/isis_spf.c:1889
#10 0x00007f30973bbf04 in thread_call (thread=0x7ffce66c38e0) at ../lib/thread.c:1990
#11 0x00007f309735497b in frr_run (master=0x55dfa91733c0) at ../lib/libfrr.c:1198
#12 0x000055dfa8029d5d in main (argc=5, argv=0x7ffce66c3b08, envp=0x7ffce66c3b38) at ../isisd/isis_main.c:273
(gdb) f 3
#3  0x000055dfa805512b in isis_spf_process_lsp (spftree=0x55dfa950eee0, lsp=0x55dfa94cb590, cost=10, depth=1, root_sysid=0x55dfa950ef6c "", parent=0x55dfa952fca0)
    at ../isisd/isis_spf.c:898
898     ../isisd/isis_spf.c: No such file or directory.
(gdb) p te_neighs
$1 = (struct isis_item_list *) 0x120
(gdb) p lsp->tlvs
$2 = (struct isis_tlvs *) 0x0
(gdb) p lsp->hdr
$3 = {pdu_len = 27, rem_lifetime = 0, lsp_id = "\000\000\000\000\000\001\000\001", seqno = 4, checksum = 59918, lsp_bits = 1 '\001'}

The backtrace provided above pertains to version 8.5.4, but it seems that the same issue exists in the code of the master branch as well.

I have reviewed the process for calculating the SPT based on the LSP, and isis_spf_process_lsp() is the only function that does not check whether the TLVs in the fragments are empty. Therefore, I believe that modifying this function alone should be sufficient. If the TLVs of the current fragment are already empty, we do not need to continue processing subsequent fragments. This is consistent with the behavior where we do not process fragments if the TLVs of the first fragment are empty.
Of course, one could argue that lsp_purge() should still retain the TLV memory, freeing it and then reallocating it if needed. However, this is a debatable point because in some scenarios, it is permissible for the LSP to have empty TLVs. For example, after receiving an SNP (Sequence Number PDU) message, an empty LSP (with lsp->hdr.seqno = 0) might be created by calling lsp_new. If the corresponding LSP message is discarded due to domain or area authentication failure, the TLV memory wouldn't be allocated.

Test scenario:
In an LFA network, importing a sufficient number of static routes to cause LSP fragmentation, and then rolling back the imported static routes so that the LSP is no longer fragmented, can easily result in this issue.

Signed-off-by: zhou-run <zhou.run@h3c.com>
(cherry picked from commit e905177a8c)
2024-07-16 14:07:50 +00:00
.github ci: do apt-get update before installing required modules 2024-06-08 17:29:19 -04:00
alpine docker: Fix post function for Alpine build (package) 2024-03-09 09:33:40 +02:00
babeld babeld: changes for code maintainability 2024-02-20 00:25:27 +05:30
bfdd bfdd: fix BFD_GETCBIT 2024-04-15 01:57:16 +03:00
bgpd bgpd: Ignore RFC8212 for BGP Confederations 2024-07-01 14:19:50 +00:00
debian debian: libyang3 2024-05-08 01:48:06 +02:00
doc doc: Add reloading script into Python dependency section 2024-06-11 15:23:24 +00:00
docker Merge pull request #16143 from eremcan/patch-1 2024-06-07 10:49:55 +03:00
eigrpd *: Modify agentx to be allowed to be called 2024-05-10 10:16:29 -04:00
fpm *: add XREF_SETUP() to libraries and utilites 2024-05-02 23:03:08 +02:00
gdb lib: add simplified native msg support 2023-12-26 08:34:56 -05:00
grpc build: throw in a few more XREF_SETUP 2024-05-09 18:02:49 +02:00
include build: include our own copy of if.h and dependencies 2024-04-26 17:11:53 +02:00
isisd isisd: fix crash when calculating the neighbor spanning tree based on the fragmented LSP 2024-07-16 14:07:50 +00:00
ldpd ldpd: fix wrong gtsm count 2024-07-02 17:50:22 +00:00
lib lib: fix incorrect use of error checking macro 2024-06-12 18:48:19 -04:00
m4 build: add recursion limit for AX_RECURSIVE_EVAL 2024-01-27 19:01:19 +01:00
mgmtd mgmtd: add empty notif xpath map for completeness 2024-06-07 05:50:10 -04:00
mlag build: throw in a few more XREF_SETUP 2024-05-09 18:02:49 +02:00
nhrpd nhrpd: cleans up shortcut cache entries on termination 2024-06-05 10:22:57 -07:00
ospf6d Merge pull request #16050 from rgirada/ospfv3_helper 2024-06-11 11:48:05 -04:00
ospfclient *: Convert event.h to frrevent.h 2023-03-24 08:32:17 -04:00
ospfd Merge pull request #16075 from anlancs/ospfd/fix-cmd-instance 2024-05-28 13:06:43 -04:00
pathd pathd: clean up a log message 2024-04-30 14:34:58 -04:00
pbrd *: create a single registry of daemons' default port values 2024-02-01 11:40:02 -05:00
pceplib Merge pull request #15215 from donaldsharp/pceplib_fixup 2024-01-25 09:59:59 +02:00
pimd pimd: Give a clearer warning when the kernel is not compiled right 2024-05-31 11:29:40 -04:00
pkgsrc build: homologize path handling 2024-01-27 19:02:52 +01:00
python Merge pull request #15980 from donaldsharp/agentx_update 2024-05-20 22:33:01 +03:00
qpb *: add XREF_SETUP() to libraries and utilites 2024-05-02 23:03:08 +02:00
redhat debian, redhat, snapcraft: Libyang min version is 2.1.128 2024-04-16 13:45:12 +02:00
ripd ripd: Change the start value of sequence 1 to 0 2024-07-01 17:37:45 +00:00
ripngd ripngd: convert RPC commands to mgmtd 2024-04-22 16:36:23 +03:00
sharpd zebra, sharpd: add srv6 End.DX6 support 2024-04-25 13:54:25 +02:00
snapcraft debian, redhat, snapcraft: Libyang min version is 2.1.128 2024-04-16 13:45:12 +02:00
staticd zebra: fix missing static routes 2024-07-15 18:46:22 +00:00
tests tests: tweak timers to avoid frequent failures on slow CI hardware 2024-07-14 00:13:20 +00:00
tools tools/gcc-plugins: warn for suseconds_t format 2024-05-02 22:26:53 +02:00
vrrpd *: create a single registry of daemons' default port values 2024-02-01 11:40:02 -05:00
vtysh lib, vtysh, topotests: fix 'show ip[v6] access-list ... json' formatting 2024-05-14 13:22:20 +02:00
watchfrr build: homologize path handling 2024-01-27 19:02:52 +01:00
yang yang: use relative path instead of absolute one for route-map 2024-05-29 13:11:03 +02:00
zebra Merge pull request #16284 from FRRouting/mergify/bp/dev/10.1/pr-16261 2024-06-25 14:49:39 +03:00
.clang-format build: make clang-format ignore DEFUN/DEFPY 2024-05-08 21:47:14 +02:00
.dockerignore docker: Make docker image on CentOS 7 2019-11-26 19:29:30 +00:00
.flake8 style: add format checker config that matches FRR style standards 2023-04-18 05:18:26 -04:00
.git-blame-ignore-revs tools: Add black formatting commit to .git-blame-ignore-revs 2024-04-28 12:50:51 +03:00
.gitignore python: add tool to expand typesafe definitions 2024-04-29 17:37:49 +02:00
.isort.cfg style: add format checker config that matches FRR style standards 2023-04-18 05:18:26 -04:00
.pylintrc style: add format checker config that matches FRR style standards 2023-04-18 05:18:26 -04:00
.travis.yml lib: libyang2 add missed conversion 2021-05-17 22:13:59 -04:00
bootstrap.sh build: turn on automake warnings (& symlinks) 2021-04-21 15:42:37 +02:00
buildtest.sh build: update packaging & docs for dir changes 2024-01-27 19:01:19 +01:00
config.version.in build: carry --with-pkg-extra-version into tarballs 2018-10-24 15:11:50 +02:00
configure.ac Merge pull request #15885 from opensourcerouting/gcc-unrecognized-ms-anon-tag 2024-05-07 16:00:53 -04:00
COPYING *: sort out & explain licenses used in FRR 2023-02-09 12:46:13 +01:00
Makefile.am build: homologize path handling 2024-01-27 19:02:52 +01:00
README.md doc: Fix the link that points to Slack invitation in README 2022-03-24 13:13:37 +02:00
stamp-h.in Initial revision 2002-12-13 20:15:29 +00:00
version.h build: make builddir include path consistent 2021-04-21 15:42:33 +02:00

Icon

FRRouting

FRR is free software that implements and manages various IPv4 and IPv6 routing protocols. It runs on nearly all distributions of Linux and BSD and supports all modern CPU architectures.

FRR currently supports the following protocols:

  • BGP
  • OSPFv2
  • OSPFv3
  • RIPv1
  • RIPv2
  • RIPng
  • IS-IS
  • PIM-SM/MSDP
  • LDP
  • BFD
  • Babel
  • PBR
  • OpenFabric
  • VRRP
  • EIGRP (alpha)
  • NHRP (alpha)

Installation & Use

For source tarballs, see the releases page.

For Debian and its derivatives, use the APT repository at https://deb.frrouting.org/.

Instructions on building and installing from source for supported platforms may be found in the developer docs.

Once installed, please refer to the user guide for instructions on use.

Community

The FRRouting email list server is located here and offers the following public lists:

Topic List
Development dev@lists.frrouting.org
Users & Operators frog@lists.frrouting.org
Announcements announce@lists.frrouting.org

For chat, we currently use Slack. You can join by clicking the "Slack" link under the Participate section of our website.

Contributing

FRR maintains developer's documentation which contains the project workflow and expectations for contributors. Some technical documentation on project internals is also available.

We welcome and appreciate all contributions, no matter how small!

Security

To report security issues, please use our security mailing list:

security [at] lists.frrouting.org