Skip to content

Use after free below update_syscallbuf_fds_disabled #3475

@bernhardu

Description

@bernhardu

I ran the tests with a force32bit build, but found the test reverse_step_breakpoint failing.
A git bisect seems to point to f46af28 as first broken commit.

As I had trouble to record rr itself, I undusted my asan patches and it shows the same use after free for x86_64.
Below is a manual replay of the test.

$ export ASAN_OPTIONS=fast_unwind_on_malloc=0
$ bin/rr replay --debugger-option=-q /tmp/rr-test-reverse_step_breakpoint-2KELOrNOA/simple-2KELOrNOA-0
Reading symbols from /tmp/rr-test-reverse_step_breakpoint-2KELOrNOA/simple-2KELOrNOA-0/mmap_hardlink_4_simple-2KELOrNOA...
Really redefine built-in command "restart"? (y or n) [answered Y; input not from terminal]
Really redefine built-in command "jump"? (y or n) [answered Y; input not from terminal]
Remote debugging using 127.0.0.1:40258
Reading symbols from /lib64/ld-linux-x86-64.so.2...
Reading symbols from /usr/lib/debug/.build-id/4f/536ac1cd2e8806aed8556ea7795c47404de8a9.debug...
BFD: warning: system-supplied DSO at 0x6fffd000 has a section extending past end of file
0x00007faeb98699c0 in _start () from /lib64/ld-linux-x86-64.so.2
(rr) b main
Breakpoint 1 at 0x55817cc4a29a: file .../rr/src/test/simple.c, line 6.
(rr) cont
Continuing.

Breakpoint 1, main () at .../rr/src/test/simple.c:6
6         atomic_puts("EXIT-SUCCESS");
(rr) next
EXIT-SUCCESS
7         return 0;
(rr) b
Breakpoint 2 at 0x55817cc4a2a9: file .../rr/src/test/simple.c, line 7.
(rr) reverse-next
=================================================================
==695618==ERROR: AddressSanitizer: heap-use-after-free on address 0x617000005ba0 at pc 0x56148d37f34a bp 0x7fffb4bfe060 sp 0x7fffb4bfe058
READ of size 8 at 0x617000005ba0 thread T0
    #0 0x56148d37f349 in std::_Rb_tree<rr::Task*, rr::Task*, std::_Identity<rr::Task*>, std::less<rr::Task*>, std::allocator<rr::Task*> >::begin() const /usr/include/c++/12/bits/stl_tree.h:1000
    #1 0x56148d37f349 in std::set<rr::Task*, std::less<rr::Task*>, std::allocator<rr::Task*> >::begin() const /usr/include/c++/12/bits/stl_set.h:345
    #2 0x56148d37f349 in rr::FdTable::update_syscallbuf_fds_disabled(int) .../rr/src/FdTable.cc:182
    #3 0x56148d37f53b in rr::FdTable::did_close(int) .../rr/src/FdTable.cc:146
    #4 0x56148d8df69f in void rr::Task::on_syscall_exit_arch<rr::X64Arch>(int, rr::Registers const&) .../rr/src/Task.cc:670
    #5 0x56148d8a209a in operator() .../rr/src/Task.cc:839
    #6 0x56148d8a209a in with_converted_registers<void, rr::Task::on_syscall_exit(int, rr::SupportedArch, const rr::Registers&)::<lambda(const rr::Registers&)> > .../rr/src/Registers.h:624
    #7 0x56148d8a223a in rr::Task::on_syscall_exit(int, rr::SupportedArch, rr::Registers const&) .../rr/src/Task.cc:838
    #8 0x56148d714791 in rr::ReplaySession::exit_syscall(rr::ReplayTask*) .../rr/src/ReplaySession.cc:659
    #9 0x56148d736a72 in rr::ReplaySession::try_one_trace_step(rr::ReplayTask*, rr::ReplaySession::StepConstraints const&) .../rr/src/ReplaySession.cc:1606
    #10 0x56148d73b7a0 in rr::ReplaySession::replay_step(rr::ReplaySession::StepConstraints const&) .../rr/src/ReplaySession.cc:1922
    #11 0x56148d7b6b35 in rr::ReplayTimeline::reverse_singlestep(rr::ReplayTimeline::Mark const&, rr::TaskishUid<rr::Task> const&, long, std::function<bool (rr::ReplayTask*, rr::BreakStatus const&)> const&, std::function<bool ()> const&) .../rr/src/ReplayTimeline.cc:1232
    #12 0x56148d7c5557 in rr::ReplayTimeline::reverse_singlestep(rr::TaskishUid<rr::Task> const&, long, std::function<bool (rr::ReplayTask*, rr::BreakStatus const&)> const&, std::function<bool ()> const&) .../rr/src/ReplayTimeline.cc:1492
    #13 0x56148d430410 in rr::GdbServer::debug_one_step(rr::GdbRequest&) .../rr/src/GdbServer.cc:1412
    #14 0x56148d43498a in rr::GdbServer::serve_replay(rr::GdbServer::ConnectionFlags const&) .../rr/src/GdbServer.cc:1831
    #15 0x56148d70b8f1 in replay .../rr/src/ReplayCommand.cc:518
    #16 0x56148d70b8f1 in rr::ReplayCommand::run(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&) .../rr/src/ReplayCommand.cc:632
    #17 0x56148d286e8e in main .../rr/src/main.cc:299
    #18 0x7fab92446189 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #19 0x7fab92446244 in __libc_start_main_impl ../csu/libc-start.c:381
    #20 0x56148d286fd0 in _start (.../obj/bin/rr+0xfdfd0)

0x617000005ba0 is located 32 bytes inside of 736-byte region [0x617000005b80,0x617000005e60)
freed by thread T0 here:
    #0 0x7fab92aba3c8 in operator delete(void*, unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:164
    #1 0x56148d88d910 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() /usr/include/c++/12/bits/shared_ptr_base.h:346
    #2 0x56148d88d910 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() /usr/include/c++/12/bits/shared_ptr_base.h:317
    #3 0x56148d88d910 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() /usr/include/c++/12/bits/shared_ptr_base.h:1071
    #4 0x56148d88d910 in std::__shared_ptr<rr::AddressSpace, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() /usr/include/c++/12/bits/shared_ptr_base.h:1524
    #5 0x56148d88d910 in std::shared_ptr<rr::AddressSpace>::~shared_ptr() /usr/include/c++/12/bits/shared_ptr.h:175
    #6 0x56148d88d910 in rr::Task::~Task() .../rr/src/Task.cc:267
    #7 0x56148d7842e6 in rr::ReplayTask::~ReplayTask() .../rr/src/ReplayTask.h:17
    #8 0x56148d7842e6 in rr::ReplayTask::~ReplayTask() .../rr/src/ReplayTask.h:17
    #9 0x56148d813ff9 in rr::Session::kill_all_tasks() .../rr/src/Session.cc:231
    #10 0x56148d719738 in rr::ReplaySession::~ReplaySession() .../rr/src/ReplaySession.cc:234
    #11 0x56148d7402d5 in rr::ReplaySession::~ReplaySession() .../rr/src/ReplaySession.cc:238
    #12 0x56148d7402d5 in std::_Sp_counted_ptr<rr::ReplaySession*, (__gnu_cxx::_Lock_policy)2>::_M_dispose() /usr/include/c++/12/bits/shared_ptr_base.h:428
    #13 0x56148d2dcb3d in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() /usr/include/c++/12/bits/shared_ptr_base.h:346
    #14 0x56148d2dcb3d in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() /usr/include/c++/12/bits/shared_ptr_base.h:317
    #15 0x56148d79d2c9 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() /usr/include/c++/12/bits/shared_ptr_base.h:1071
    #16 0x56148d79d2c9 in std::__shared_ptr<rr::ReplaySession, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() /usr/include/c++/12/bits/shared_ptr_base.h:1524
    #17 0x56148d79d2c9 in std::__shared_ptr<rr::ReplaySession, (__gnu_cxx::_Lock_policy)2>::operator=(std::__shared_ptr<rr::ReplaySession, (__gnu_cxx::_Lock_policy)2>&&) /usr/include/c++/12/bits/shared_ptr_base.h:1620
    #18 0x56148d79d2c9 in std::shared_ptr<rr::ReplaySession>::operator=(std::shared_ptr<rr::ReplaySession>&&) /usr/include/c++/12/bits/shared_ptr.h:440
    #19 0x56148d79d2c9 in rr::ReplayTimeline::seek_to_before_key(rr::ReplayTimeline::MarkKey const&) .../rr/src/ReplayTimeline.cc:345
    #20 0x56148d7b4c76 in rr::ReplayTimeline::reverse_singlestep(rr::ReplayTimeline::Mark const&, rr::TaskishUid<rr::Task> const&, long, std::function<bool (rr::ReplayTask*, rr::BreakStatus const&)> const&, std::function<bool ()> const&) .../rr/src/ReplayTimeline.cc:1197
    #21 0x56148d7c5557 in rr::ReplayTimeline::reverse_singlestep(rr::TaskishUid<rr::Task> const&, long, std::function<bool (rr::ReplayTask*, rr::BreakStatus const&)> const&, std::function<bool ()> const&) .../rr/src/ReplayTimeline.cc:1492
    #22 0x56148d430410 in rr::GdbServer::debug_one_step(rr::GdbRequest&) .../rr/src/GdbServer.cc:1412
    #23 0x56148d43498a in rr::GdbServer::serve_replay(rr::GdbServer::ConnectionFlags const&) .../rr/src/GdbServer.cc:1831
    #24 0x56148d70b8f1 in replay .../rr/src/ReplayCommand.cc:518
    #25 0x56148d70b8f1 in rr::ReplayCommand::run(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&) .../rr/src/ReplayCommand.cc:632
    #26 0x56148d286e8e in main .../rr/src/main.cc:299
    #27 0x7fab92446189 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #28 0x7fab92446244 in __libc_start_main_impl ../csu/libc-start.c:381
    #29 0x56148d286fd0 in _start (.../obj/bin/rr+0xfdfd0)

previously allocated by thread T0 here:
    #0 0x7fab92ab94c8 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95
    #1 0x56148d836b0f in rr::Session::clone(rr::Task*, std::shared_ptr<rr::AddressSpace>) .../rr/src/Session.cc:120
    #2 0x56148d8ab2a5 in rr::Task::clone(rr::Task::CloneReason, int, rr::remote_ptr<void>, rr::remote_ptr<void>, rr::remote_ptr<int>, int, int, unsigned int, rr::Session*, std::shared_ptr<rr::FdTable>, std::shared_ptr<rr::ThreadGroup>) .../rr/src/Task.cc:2326
    #3 0x56148d89c8ee in rr::Task::os_clone(rr::Task::CloneReason, rr::Session*, rr::AutoRemoteSyscalls&, int, unsigned int, unsigned int, std::shared_ptr<rr::FdTable>, std::shared_ptr<rr::ThreadGroup>, rr::remote_ptr<void>, rr::remote_ptr<int>, rr::remote_ptr<void>, rr::remote_ptr<int>) .../rr/src/Task.cc:3214
    #4 0x56148d89d234 in rr::Task::os_fork_into(rr::Session*, std::shared_ptr<rr::FdTable>) .../rr/src/Task.cc:2453
    #5 0x56148d82bea1 in rr::Session::copy_state_to(rr::Session&, rr::EmuFs&, rr::EmuFs&) .../rr/src/Session.cc:682
    #6 0x56148d720ccc in rr::ReplaySession::clone() .../rr/src/ReplaySession.cc:249
    #7 0x56148d7b0eef in rr::ReplayTimeline::add_explicit_checkpoint() .../rr/src/ReplayTimeline.cc:297
    #8 0x56148d7b3750 in rr::ReplayTimeline::set_short_checkpoint() .../rr/src/ReplayTimeline.cc:1660
    #9 0x56148d7c09c4 in rr::ReplayTimeline::reverse_continue(std::function<bool (rr::ReplayTask*, rr::BreakStatus const&)> const&, std::function<bool ()> const&) .../rr/src/ReplayTimeline.cc:1037
    #10 0x56148d431302 in rr::GdbServer::debug_one_step(rr::GdbRequest&) .../rr/src/GdbServer.cc:1407
    #11 0x56148d43498a in rr::GdbServer::serve_replay(rr::GdbServer::ConnectionFlags const&) .../rr/src/GdbServer.cc:1831
    #12 0x56148d70b8f1 in replay .../rr/src/ReplayCommand.cc:518
    #13 0x56148d70b8f1 in rr::ReplayCommand::run(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&) .../rr/src/ReplayCommand.cc:632
    #14 0x56148d286e8e in main .../rr/src/main.cc:299
    #15 0x7fab92446189 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #16 0x7fab92446244 in __libc_start_main_impl ../csu/libc-start.c:381
    #17 0x56148d286fd0 in _start (.../obj/bin/rr+0xfdfd0)

SUMMARY: AddressSanitizer: heap-use-after-free /usr/include/c++/12/bits/stl_tree.h:1000 in std::_Rb_tree<rr::Task*, rr::Task*, std::_Identity<rr::Task*>, std::less<rr::Task*>, std::allocator<rr::Task*> >::begin() const
Shadow bytes around the buggy address:
  0x0c2e7fff8b20: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2e7fff8b30: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2e7fff8b40: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2e7fff8b50: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa
  0x0c2e7fff8b60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c2e7fff8b70: fd fd fd fd[fd]fd fd fd fd fd fd fd fd fd fd fd
  0x0c2e7fff8b80: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2e7fff8b90: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2e7fff8ba0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2e7fff8bb0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2e7fff8bc0: fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa
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
==695618==ABORTING
Remote connection closed

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions