Use after free in ospf_topo2
Description
Running ospf_topo2 test in topotests I am getting:
=================================================================
==4079502==ERROR: AddressSanitizer: heap-use-after-free on address 0x6070000fbfe8 at pc 0x7f0aaacf24db bp 0x7fff768ca370 sp 0x7fff768ca360
READ of size 8 at 0x6070000fbfe8 thread T0
#0 0x7f0aaacf24da in _rb_next lib/openbsd-tree.c:455
#1 0x5581a7aba68e in zebra_neigh_rb_head_RB_NEXT zebra/zebra_neigh.h:34
#2 0x5581a7abb701 in zebra_neigh_del_all zebra/zebra_neigh.c:162
#3 0x5581a78dfba2 in zebra_interface_down_update zebra/redistribute.c:532
#4 0x5581a78b65e2 in if_down zebra/interface.c:1052
#5 0x5581a78bc5cb in zebra_if_dplane_ifp_handling zebra/interface.c:2129
#6 0x5581a78bd553 in zebra_if_dplane_result zebra/interface.c:2268
#7 0x5581a7a32f6c in rib_process_dplane_results zebra/zebra_rib.c:4956
#8 0x7f0aaad8ab40 in event_call lib/event.c:1995
#9 0x7f0aaac53ce8 in frr_run lib/libfrr.c:1232
#10 0x5581a78dae3c in main zebra/main.c:526
#11 0x7f0aaa029d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#12 0x7f0aaa029e3f in __libc_start_main_impl ../csu/libc-start.c:392
#13 0x5581a7899ef4 in _start (/usr/lib/frr/zebra+0x1a5ef4)
0x6070000fbfe8 is located 56 bytes inside of 80-byte region [0x6070000fbfb0,0x6070000fc000)
freed by thread T0 here:
#0 0x7f0aab2be470 in __interceptor_free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:52
#1 0x7f0aaac82858 in qfree lib/memory.c:130
#2 0x5581a7abb4d3 in zebra_neigh_free zebra/zebra_neigh.c:135
#3 0x5581a7abb5ec in zebra_neigh_del zebra/zebra_neigh.c:150
#4 0x5581a7abb6e6 in zebra_neigh_del_all zebra/zebra_neigh.c:163
#5 0x5581a78dfba2 in zebra_interface_down_update zebra/redistribute.c:532
#6 0x5581a78b65e2 in if_down zebra/interface.c:1052
#7 0x5581a78bc5cb in zebra_if_dplane_ifp_handling zebra/interface.c:2129
#8 0x5581a78bd553 in zebra_if_dplane_result zebra/interface.c:2268
#9 0x5581a7a32f6c in rib_process_dplane_results zebra/zebra_rib.c:4956
#10 0x7f0aaad8ab40 in event_call lib/event.c:1995
#11 0x7f0aaac53ce8 in frr_run lib/libfrr.c:1232
#12 0x5581a78dae3c in main zebra/main.c:526
#13 0x7f0aaa029d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
previously allocated by thread T0 here:
#0 0x7f0aab2bf2e7 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:77
#1 0x7f0aaac82706 in qcalloc lib/memory.c:105
#2 0x5581a7abaec0 in zebra_neigh_new zebra/zebra_neigh.c:80
#3 0x5581a7abb8fc in zebra_neigh_add zebra/zebra_neigh.c:187
#4 0x5581a7900af3 in netlink_ipneigh_change zebra/rt_netlink.c:4418
#5 0x5581a790209b in netlink_neigh_change zebra/rt_netlink.c:4637
#6 0x5581a78cbdec in netlink_information_fetch zebra/kernel_netlink.c:415
#7 0x5581a78d01fa in netlink_parse_info zebra/kernel_netlink.c:1163
#8 0x5581a78cc146 in kernel_read zebra/kernel_netlink.c:510
#9 0x7f0aaad8ab40 in event_call lib/event.c:1995
#10 0x7f0aaac53ce8 in frr_run lib/libfrr.c:1232
#11 0x5581a78dae3c in main zebra/main.c:526
#12 0x7f0aaa029d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
Version
master
How to reproduce
Run address sanitizer
Expected behavior
no use after free
Actual behavior
use after free
Additional context
No response
Checklist
- [X] I have searched the open issues for this bug.
- [X] I have not included sensitive information in this report.
This is really a strange since the violation is in the OpenBSD Red/Black tree safe iterator for the Zebra neighbor. I'm not too fond of the iterator usage of the comma operator but it should work unless there is some compiler optimization that reorders things:
for ((_e) = RB_MIN(_name, (_head));
(_e) != NULL && ((_n) = RB_NEXT(_name, (_e)), 1); (_e) = (_n))
Since zebra_neigh_free() always removes the zeighbor from the RB tree prior to freeing, there should never be a stale neighbor entry in the RB tree.
Also, my attempts at running the address-sanitizer were mixed. Although the test fails, I don't see how to get the stack that you got above. This is all I get indicating a failure:
test_ospf_topo2/r1 /bin/bash -c vtysh -d zebra < /tmp/tmpsnb23us8 stdout: AddressSanitizer:DEADLYSIGNAL AddressSanitizer:DEADLYSIGNAL AddressSanitizer:DEADLYSIGNAL AddressSanitizer:DEADLYSIGNAL AddressSanitizer:DEADLYSIGNAL
oh man - that del_all loop is dreadful - it looks like it touches every node in the tree, even though it could start with the first entry with the ifindex, and stop when there are no more entries that match the ifindex.
This issue is stale because it has been open 180 days with no activity. Comment or remove the autoclose label in order to avoid having this issue closed.
This issue will be automatically closed in the specified period unless there is further activity.