Project

General

Profile

Actions

Bug #3319

closed

TestFibUpdates/EraseFace/WithInheritedFace use-after-free

Added by Davide Pesavento over 8 years ago. Updated about 8 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
RIB
Target version:
Start date:
Due date:
% Done:

100%

Estimated time:

Description

$ ./build/unit-tests-rib -t TestFibUpdates/EraseFace/WithInheritedFace
Running 1 test case...
=================================================================
==4125==ERROR: AddressSanitizer: heap-use-after-free on address 0x60b0000048a8 at pc 0x0000004e4ec2 bp 0x7fffcbb1e5c0 sp 0x7fffcbb1e5b0
READ of size 8 at 0x60b0000048a8 thread T0
    #0 0x4e4ec1 in nfd::rib::FibUpdater::createFibUpdatesForNewRoute(nfd::rib::RibEntry const&, nfd::rib::Route const&, bool) ../rib/fib-updater.cpp:427
    #1 0x4e701d in nfd::rib::FibUpdater::computeUpdatesForUnregistration(nfd::rib::RibUpdate const&) ../rib/fib-updater.cpp:179
    #2 0x4e74c8 in nfd::rib::FibUpdater::computeUpdates(nfd::rib::RibUpdateBatch const&) ../rib/fib-updater.cpp:81
    #3 0x4ee00c in nfd::rib::FibUpdater::computeAndSendFibUpdates(nfd::rib::RibUpdateBatch const&, std::function<void (std::__cxx11::list<nfd::rib::RibUpdate, std::allocator<nfd::rib::RibUpdate> >)> const&, std::function<void (unsigned int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)> const&) ../rib/fib-updater.cpp:63
    #4 0x544a47 in nfd::rib::Rib::sendBatchFromQueue() ../rib/rib.cpp:400
    #5 0x54568f in nfd::rib::Rib::beginApplyUpdate(nfd::rib::RibUpdate const&, std::function<void ()> const&, std::function<void (unsigned int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)> const&) ../rib/rib.cpp:346
    #6 0x45a3a0 in nfd::rib::tests::FibUpdatesFixture::simulateSuccessfulResponse(nfd::rib::RibUpdate const&) (/home/davide/NFD/build/unit-tests-rib+0x45a3a0)
    #7 0x45e58f in nfd::rib::tests::FibUpdatesFixture::eraseRoute(ndn::Name const&, unsigned long, unsigned long) (/home/davide/NFD/build/unit-tests-rib+0x45e58f)
    #8 0x44ed68 in nfd::rib::tests::TestFibUpdates::EraseFace::WithInheritedFace::test_method() ../tests/rib/fib-updates-erase-face.t.cpp:69
    #9 0x458814 in WithInheritedFace_invoker ../tests/rib/fib-updates-erase-face.t.cpp:60
    #10 0x43b48e in boost::unit_test::ut_detail::unused boost::unit_test::ut_detail::invoker<boost::unit_test::ut_detail::unused>::invoke<void (*)()>(void (*&)()) /usr/include/boost/test/utils/callback.hpp:56
    #11 0x43b48e in boost::unit_test::ut_detail::callback0_impl_t<boost::unit_test::ut_detail::unused, void (*)()>::invoke() /usr/include/boost/test/utils/callback.hpp:89
    #12 0x7f7a8145acd0  (/usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.so.1.58.0+0x6acd0)
    #13 0x7f7a8143a8b5 in boost::execution_monitor::catch_signals(boost::unit_test::callback0<int> const&) (/usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.so.1.58.0+0x4a8b5)
    #14 0x7f7a8143b0d2 in boost::execution_monitor::execute(boost::unit_test::callback0<int> const&) (/usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.so.1.58.0+0x4b0d2)
    #15 0x7f7a8145ae01 in boost::unit_test::unit_test_monitor_t::execute_and_translate(boost::unit_test::test_case const&) (/usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.so.1.58.0+0x6ae01)
    #16 0x7f7a81441fbd in boost::unit_test::framework_impl::visit(boost::unit_test::test_case const&) (/usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.so.1.58.0+0x51fbd)
    #17 0x7f7a8147848a in boost::unit_test::traverse_test_tree(boost::unit_test::test_suite const&, boost::unit_test::test_tree_visitor&) (/usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.so.1.58.0+0x8848a)
    #18 0x7f7a8147848a in boost::unit_test::traverse_test_tree(boost::unit_test::test_suite const&, boost::unit_test::test_tree_visitor&) (/usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.so.1.58.0+0x8848a)
    #19 0x7f7a8147848a in boost::unit_test::traverse_test_tree(boost::unit_test::test_suite const&, boost::unit_test::test_tree_visitor&) (/usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.so.1.58.0+0x8848a)
    #20 0x7f7a8143d915 in boost::unit_test::framework::run(unsigned long, bool) (/usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.so.1.58.0+0x4d915)
    #21 0x7f7a814592a6 in boost::unit_test::unit_test_main(bool (*)(), int, char**) (/usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.so.1.58.0+0x692a6)
    #22 0x55b2f0 in main /usr/include/boost/test/unit_test.hpp:59
    #23 0x7f7a800efa3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x20a3f)
    #24 0x41edd8 in _start (/home/davide/NFD/build/unit-tests-rib+0x41edd8)

0x60b0000048a8 is located 56 bytes inside of 112-byte region [0x60b000004870,0x60b0000048e0)
freed by thread T0 here:
    #0 0x7f7a81b5eeaa in operator delete(void*) (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x99eaa)
    #1 0x5193c6 in __gnu_cxx::new_allocator<nfd::rib::Route>::deallocate(nfd::rib::Route*, unsigned long) /usr/include/c++/5/ext/new_allocator.h:110
    #2 0x5193c6 in std::allocator_traits<std::allocator<nfd::rib::Route> >::deallocate(std::allocator<nfd::rib::Route>&, nfd::rib::Route*, unsigned long) /usr/include/c++/5/bits/alloc_traits.h:386
    #3 0x5193c6 in std::_Vector_base<nfd::rib::Route, std::allocator<nfd::rib::Route> >::_M_deallocate(nfd::rib::Route*, unsigned long) /usr/include/c++/5/bits/stl_vector.h:178
    #4 0x5193c6 in std::_Vector_base<nfd::rib::Route, std::allocator<nfd::rib::Route> >::~_Vector_base() /usr/include/c++/5/bits/stl_vector.h:160
    #5 0x5193c6 in std::vector<nfd::rib::Route, std::allocator<nfd::rib::Route> >::~vector() /usr/include/c++/5/bits/stl_vector.h:425
    #6 0x5193c6 in nfd::rib::RibEntry::getRouteWithSecondLowestCostByFaceId(unsigned long) const ../rib/rib-entry.cpp:203

previously allocated by thread T0 here:
    #0 0x7f7a81b5e8b2 in operator new(unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x998b2)
    #1 0x448e42 in void std::vector<nfd::rib::Route, std::allocator<nfd::rib::Route> >::_M_emplace_back_aux<nfd::rib::Route const&>(nfd::rib::Route const&) (/home/davide/NFD/build/unit-tests-rib+0x448e42)

SUMMARY: AddressSanitizer: heap-use-after-free ../rib/fib-updater.cpp:427 nfd::rib::FibUpdater::createFibUpdatesForNewRoute(nfd::rib::RibEntry const&, nfd::rib::Route const&, bool)
Shadow bytes around the buggy address:
  0x0c167fff88c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c167fff88d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c167fff88e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c167fff88f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c167fff8900: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fd fd
=>0x0c167fff8910: fd fd fd fd fd[fd]fd fd fd fd fd fd fa fa fa fa
  0x0c167fff8920: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c167fff8930: fd fd fa fa fa fa fa fa fa fa 00 00 00 00 00 00
  0x0c167fff8940: 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa fa
  0x0c167fff8950: fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa
  0x0c167fff8960: fa fa fa fa fa fa fd fd fd fd fd fd 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
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  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
==4125==ABORTING

Related issues 1 (0 open1 closed)

Blocks NFD - Task #2589: CI: enable AddressSanitizer for unit testsClosedDavide Pesavento

Actions
Actions #1

Updated by Davide Pesavento over 8 years ago

  • Blocks Task #2589: CI: enable AddressSanitizer for unit tests added
Actions #2

Updated by Davide Pesavento over 8 years ago

The same use-after-free happens in the "MultipleFaces" test case.

Actions #3

Updated by Junxiao Shi over 8 years ago

  • Assignee set to Vince Lehman

@Vince authored these test cases and the FibUpdater.

Actions #4

Updated by Vince Lehman over 8 years ago

@Davide Could you please provide the steps/commands to reproduce this error? Thanks.

Actions #5

Updated by Davide Pesavento over 8 years ago

$ CXXFLAGS="-Og -g3 -pedantic -Wall -Wextra -Werror -Wno-unused-parameter -Wno-error=maybe-uninitialized -pipe -fsanitize=address" LINKFLAGS="-fsanitize=address" ./waf configure --debug --with-tests
$ ./waf
$ ./build/unit-tests-rib -t TestFibUpdates/EraseFace/WithInheritedFace
Actions #6

Updated by Davide Pesavento over 8 years ago

You need gcc-4.8 or later I think.

Actions #7

Updated by Davide Pesavento about 8 years ago

Vince, any updates on this?

Actions #8

Updated by Vince Lehman about 8 years ago

Davide Pesavento wrote:

Vince, any updates on this?

I was unable to reproduce the issue previously, but I only had a little bit of time to try. Which OS and version were you using? I will begin working on reproducing and fixing this as soon as possible.

Actions #9

Updated by Davide Pesavento about 8 years ago

64-bit Ubuntu 15.10

Actions #10

Updated by Vince Lehman about 8 years ago

  • Status changed from New to In Progress
Actions #11

Updated by Vince Lehman about 8 years ago

I am able to reproduce the error; the following is a summary of the problem:

The RibEntry::getRouteWithSecondLowestCostByFaceId() method adds copies of routes to a locally allocated vector: rib-entry.cpp:206

The method returns a pointer to one of the copies in the vector, but the vector is destroyed when the method returns: rib-entry.cpp:218

Actions #12

Updated by Vince Lehman about 8 years ago

  • Status changed from In Progress to Code review
  • % Done changed from 0 to 90
Actions #13

Updated by Davide Pesavento about 8 years ago

  • Status changed from Code review to Closed
  • Target version set to v0.5
  • % Done changed from 90 to 100
Actions

Also available in: Atom PDF