AddressSanitizer: heap-use-after-free lib/timer.h:61 in tm_active

Maria Matejka maria.matejka at nic.cz
Fri May 26 16:48:43 CEST 2023


Hello Michał,

this issue seems valid. Although I'm quite sure that it is almost 
impossible to hit it in real deployment, we shall definitely fix it. As 
soon as we get back from RIPE, we'll address it.

Thank you for your bugreport.

Maria

On 5/26/23 16:12, Zagorski, Michal via Bird-users wrote:
> Hello,
> During stress testing I found invalid read within bgp.
> I use gcc's Address Sanitizer, building with config:
> CFLAGS="-D_FORTIFY_SOURCE=2 -fsanitize=address -fno-omit-frame-pointer
> -ggdb3 -g3 -O0" LDFLAGS="-fsanitize=address -fno-omit-frame-pointer"
> LIBS="-lasan" ./configure --with-protocols="bgp static"
> When breaking session links and querying "show protocols all" after expired
> hold timer, it hits with report:
> =================================================================
> ==3476100==ERROR: AddressSanitizer: heap-use-after-free on address
> 0x606000245508 at pc 0x56497e7af450 bp 0x7ffcae09e400 sp 0x7ffcae09e3f8
> READ of size 8 at 0x606000245508 thread T0
>      #0 0x56497e7af44f in tm_active lib/timer.h:61
>      #1 0x56497e7c4e12 in bgp_show_proto_info proto/bgp/bgp.c:2624
>      #2 0x56497e76cb40 in proto_cmd_show nest/proto.c:2082
>      #3 0x56497e76d9bb in proto_apply_cmd_patt nest/proto.c:2232
>      #4 0x56497e76db9c in proto_apply_cmd nest/proto.c:2248
>      #5 0x56497e6762e6 in cf_parse nest/config.Y:623
>      #6 0x56497e69089c in cli_parse conf/conf.c:180
>      #7 0x56497e751001 in cli_command nest/cli.c:273
>      #8 0x56497e751273 in cli_event nest/cli.c:302
>      #9 0x56497e71f7a6 in ev_run lib/event.c:86
>      #10 0x56497e71f9af in ev_run_list lib/event.c:159
>      #11 0x56497e813e34 in io_loop sysdep/unix/io.c:2216
>      #12 0x56497e820b45 in main sysdep/unix/main.c:958
>      #13 0x7fa940846189 in __libc_start_call_main
> ../sysdeps/nptl/libc_start_call_main.h:58
>      #14 0x7fa940846244 in __libc_start_main_impl ../csu/libc-start.c:381
>      #15 0x56497e65c940 in _start (/home/mzagorsk/git/cz-bird/bird+0x48940)
>
> 0x606000245508 is located 40 bytes inside of 64-byte region
> [0x6060002454e0,0x606000245520)
> freed by thread T0 here:
>      #0 0x7fa940ab76a8 in __interceptor_free
> ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:52
>      #1 0x56497e7376a5 in pool_free lib/resource.c:97
>      #2 0x56497e737c5f in rfree lib/resource.c:187
>      #3 0x56497e76b2bc in proto_do_down nest/proto.c:1885
>      #4 0x56497e76b56e in proto_notify_state nest/proto.c:1951
>      #5 0x56497e7b1b71 in bgp_down proto/bgp/bgp.c:475
>      #6 0x56497e7b1d8d in bgp_decision proto/bgp/bgp.c:493
>      #7 0x56497e71f7a6 in ev_run lib/event.c:86
>      #8 0x56497e71f9af in ev_run_list lib/event.c:159
>      #9 0x56497e813e34 in io_loop sysdep/unix/io.c:2216
>      #10 0x56497e820b45 in main sysdep/unix/main.c:958
>      #11 0x7fa940846189 in __libc_start_call_main
> ../sysdeps/nptl/libc_start_call_main.h:58
>
> previously allocated by thread T0 here:
>      #0 0x7fa940ab89cf in __interceptor_malloc
> ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
>      #1 0x56497e7461d4 in bird_xmalloc lib/xmalloc.c:29
>      #2 0x56497e73800b in ralloc lib/resource.c:245
>      #3 0x56497e7434df in tm_new lib/timer.c:133
>      #4 0x56497e7af4e6 in tm_new_init lib/timer.h:74
>      #5 0x56497e7bcad7 in bgp_channel_start proto/bgp/bgp.c:1796
>      #6 0x56497e7632da in channel_do_start nest/proto.c:560
>      #7 0x56497e763c89 in channel_set_state nest/proto.c:658
>      #8 0x56497e760cb6 in proto_start_channels nest/proto.c:217
>      #9 0x56497e76b081 in proto_do_up nest/proto.c:1853
>      #10 0x56497e76b504 in proto_notify_state nest/proto.c:1938
>      #11 0x56497e7b427c in bgp_conn_enter_established_state
> proto/bgp/bgp.c:691
>      #12 0x56497e7e217a in bgp_rx_keepalive proto/bgp/packets.c:3412
>      #13 0x56497e7e2445 in bgp_rx_packet proto/bgp/packets.c:3445
>      #14 0x56497e7e2683 in bgp_rx proto/bgp/packets.c:3488
>      #15 0x56497e8122e2 in call_rx_hook sysdep/unix/io.c:1800
>      #16 0x56497e8127cb in sk_read_noflush sysdep/unix/io.c:1888
>      #17 0x56497e812a2b in sk_read sysdep/unix/io.c:1923
>      #18 0x56497e8148dd in io_loop sysdep/unix/io.c:2323
>      #19 0x56497e820b45 in main sysdep/unix/main.c:958
>      #20 0x7fa940846189 in __libc_start_call_main
> ../sysdeps/nptl/libc_start_call_main.h:58
>
> SUMMARY: AddressSanitizer: heap-use-after-free lib/timer.h:61 in tm_active
> Shadow bytes around the buggy address:
>    0x0c0c80040a50: fa fa fa fa fd fd fd fd fd fd fd fd fa fa fa fa
>    0x0c0c80040a60: fd fd fd fd fd fd fd fa fa fa fa fa fd fd fd fd
>    0x0c0c80040a70: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fa
>    0x0c0c80040a80: fa fa fa fa fd fd fd fd fd fd fd fa fa fa fa fa
>    0x0c0c80040a90: fd fd fd fd fd fd fd fa fa fa fa fa fd fd fd fd
> =>0x0c0c80040aa0: fd[fd]fd fd fa fa fa fa fd fd fd fd fd fd fd fa
>    0x0c0c80040ab0: fa fa fa fa fd fd fd fd fd fd fd fa fa fa fa fa
>    0x0c0c80040ac0: fd fd fd fd fd fd fd fa fa fa fa fa fd fd fd fd
>    0x0c0c80040ad0: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fd
>    0x0c0c80040ae0: fa fa fa fa fd fd fd fd fd fd fd fd fa fa fa fa
>    0x0c0c80040af0: fd fd fd fd fd fd fd fd fa fa fa fa fd fd fd fd
> Shadow byte legend (one shadow byte represents 8 application bytes):
>    Addressable:           00
>    Partially addressable: 01 02 03 04 05 06 07
>    Heap left redzone:       fa
>    Freed heap region:       fd
>    Stack left redzone:      f1
>    Stack mid redzone:       f2
>    Stack right redzone:     f3
>    Stack after return:      f5
>    Stack use after scope:   f8
>    Global redzone:          f9
>    Global init order:       f6
>    Poisoned by user:        f7
>    Container overflow:      fc
>    Array cookie:            ac
>    Intra object redzone:    bb
>    ASan internal:           fe
>    Left alloca redzone:     ca
>    Right alloca redzone:    cb
> ==3476100==ABORTING
> Without sanitizers, similar scenario wouldn't lead to visible crashes or
> invalid output.
>
> If I understand it correctly, after hold timers expired, protocol's memory
> pool (p->pool) is freed from event with bgp_down.
> On other event, "show protocols all" read channels' structures and got valid
> pointer c->staled_timer, as timer is mostly deactivated, second
> condition would fail.
> --
> Thanks,
> Michał Zagórski
>
-- 
Maria Matejka | BIRD Team Leader | CZ.NIC, z.s.p.o.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://trubka.network.cz/pipermail/bird-users/attachments/20230526/c9cd8fa4/attachment.htm>


More information about the Bird-users mailing list