From 3eeed525abc1267767dd266e9f75246b0f65e3b0 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Wed, 3 Jan 2024 16:13:02 +0100 Subject: [PATCH] isisd: fix _isis_spftree_del heap-use-after-free Fix the following heap-use-after-free > ==82961==ERROR: AddressSanitizer: heap-use-after-free on address 0x6020001e4750 at pc 0x55a8cc7f63ac bp 0x7ffd6948e340 sp 0x7ffd6948e330 > READ of size 8 at 0x6020001e4750 thread T0 > #0 0x55a8cc7f63ab in isis_route_node_cleanup isisd/isis_route.c:335 > #1 0x7ff25ec617c1 in route_node_free lib/table.c:75 > #2 0x7ff25ec619fc in route_table_free lib/table.c:111 > #3 0x7ff25ec61661 in route_table_finish lib/table.c:46 > #4 0x55a8cc800d83 in _isis_spftree_del isisd/isis_spf.c:397 > #5 0x55a8cc800e45 in isis_spftree_clear isisd/isis_spf.c:414 > #6 0x55a8cc80bd9a in isis_run_spf isisd/isis_spf.c:2020 > #7 0x55a8cc80c370 in isis_run_spf_with_protection isisd/isis_spf.c:2076 > #8 0x55a8cc80cf52 in isis_run_spf_cb isisd/isis_spf.c:2165 > #9 0x7ff25ec7c4dc in event_call lib/event.c:1970 > #10 0x7ff25eb64423 in frr_run lib/libfrr.c:1213 > #11 0x55a8cc7799da in main isisd/isis_main.c:318 > #12 0x7ff25e623d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 > #13 0x7ff25e623e3f in __libc_start_main_impl ../csu/libc-start.c:392 > #14 0x55a8cc778e44 in _start (/usr/lib/frr/isisd+0x109e44) > > 0x6020001e4750 is located 0 bytes inside of 16-byte region [0x6020001e4750,0x6020001e4760) > freed by thread T0 here: > #0 0x7ff25f000537 in __interceptor_free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:127 > #1 0x7ff25eb9012e in qfree lib/memory.c:130 > #2 0x55a8cc7f6485 in isis_route_table_info_free isisd/isis_route.c:351 > #3 0x55a8cc800cf4 in _isis_spftree_del isisd/isis_spf.c:395 > #4 0x55a8cc800e45 in isis_spftree_clear isisd/isis_spf.c:414 > #5 0x55a8cc80bd9a in isis_run_spf isisd/isis_spf.c:2020 > #6 0x55a8cc80c370 in isis_run_spf_with_protection isisd/isis_spf.c:2076 > #7 0x55a8cc80cf52 in isis_run_spf_cb isisd/isis_spf.c:2165 > #8 0x7ff25ec7c4dc in event_call lib/event.c:1970 > #9 0x7ff25eb64423 in frr_run lib/libfrr.c:1213 > #10 0x55a8cc7799da in main isisd/isis_main.c:318 > #11 0x7ff25e623d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 > > previously allocated by thread T0 here: > #0 0x7ff25f000a57 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154 > #1 0x7ff25eb8ffdc in qcalloc lib/memory.c:105 > #2 0x55a8cc7f63eb in isis_route_table_info_alloc isisd/isis_route.c:343 > #3 0x55a8cc80052a in _isis_spftree_init isisd/isis_spf.c:334 > #4 0x55a8cc800e51 in isis_spftree_clear isisd/isis_spf.c:415 > #5 0x55a8cc80bd9a in isis_run_spf isisd/isis_spf.c:2020 > #6 0x55a8cc80c370 in isis_run_spf_with_protection isisd/isis_spf.c:2076 > #7 0x55a8cc80cf52 in isis_run_spf_cb isisd/isis_spf.c:2165 > #8 0x7ff25ec7c4dc in event_call lib/event.c:1970 > #9 0x7ff25eb64423 in frr_run lib/libfrr.c:1213 > #10 0x55a8cc7799da in main isisd/isis_main.c:318 > #11 0x7ff25e623d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 Fixes: 7153c3cabf ("isisd: update struct isis_route_info has multiple sr info by algorithm") Signed-off-by: Louis Scalbert (cherry picked from commit 9fa9a9d865c6e0ed2454abf3961410edabb17533) --- isisd/isis_spf.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index a2230cd009..7a4b45a0de 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -378,6 +378,8 @@ isis_spftree_new(struct isis_area *area, struct lspdb_head *lspdb, static void _isis_spftree_del(struct isis_spftree *spftree) { + void *info, *backup_info; + hash_clean_and_free(&spftree->prefix_sids, NULL); isis_zebra_rlfa_unregister_all(spftree); isis_rlfa_list_clear(spftree); @@ -391,10 +393,12 @@ static void _isis_spftree_del(struct isis_spftree *spftree) list_delete(&spftree->sadj_list); isis_vertex_queue_free(&spftree->tents); isis_vertex_queue_free(&spftree->paths); - isis_route_table_info_free(spftree->route_table->info); - isis_route_table_info_free(spftree->route_table_backup->info); + info = spftree->route_table->info; + backup_info = spftree->route_table_backup->info; route_table_finish(spftree->route_table); route_table_finish(spftree->route_table_backup); + isis_route_table_info_free(info); + isis_route_table_info_free(backup_info); } void isis_spftree_del(struct isis_spftree *spftree)