Skip to content
  • Anthony Ryan's avatar
    Eliminate use-after-free in DHT Server (#120) · 856d9ca8
    Anthony Ryan authored
    Currently when a connection triggers a failed_transaction it gets
    deleted, which is the expected behavior. Unfortunately any packets
    left in the DHT packet priority queue will now have been free'd
    leading to a scenario where the process_queue is working on memory
    which may contain unpredictable data.
    
    The new behavior proposed by this patch is to also drop any queued
    packets to prevent future processing since we're throwing out that
    object for probelmatic behavior already.
    
    Notably this seems to reflect the same behavior seen in issue #68
    however I do not believe that to be a complete fix. It seems to
    decrease the probability of the issue occurring. I personally
    believe this fix should replace the one applied after #68 but am
    certainly open to further discussion on the matter.
    
    --------
    
    READ of size 4 thread 0 (rtorrent main)
    
    0. rak::socket_address_inet::address_n() const ../../rak/socket_address.h:167
    1. torrent::DhtTransaction::key(rak::socket_address const*, int) (/usr/lib64/libtorrent.so.19+0x2d9936)
    2. torrent::DhtTransaction::key(int) const (/usr/lib64/libtorrent.so.19+0x2d8d3f)
    3. torrent::DhtServer::process_queue(std::deque<torrent::DhtTransactionPacket*, std::allocator<torrent::DhtTransactionPacket*> >&, unsigned int*) libtorrent/src/dht/dht_server.cc:801
    4. torrent::DhtServer::event_write() libtorrent/src/dht/dht_server.cc:866
    5. torrent::PollEPoll::perform() libtorrent/src/torrent/poll_epoll.cc:190
    6. torrent::PollEPoll::do_poll(long, int) libtorrent/src/torrent/poll_epoll.cc:219
    7. torrent::thread_base::event_loop(torrent::thread_base*) libtorrent/src/torrent/utils/thread_base.cc:174
    8. main rtorrent/src/main.cc:867
    9. __libc_start_main (/lib64/libc.so.6+0x20733)
    10. _start (/usr/bin/rtorrent+0x9bce8)
    
    freed by thread 0 (rtorrent main) here:
    
    0. operator delete(void*) (/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/libasan.so.1+0x62e47)
    1. torrent::DhtTransactionPing::~DhtTransactionPing() libtorrent/src/dht/dht_transaction.h:359
    2. torrent::DhtServer::failed_transaction(std::_Rb_tree_iterator<std::pair<unsigned long const, torrent::DhtTransaction*> >, bool) libtorrent/src/dht/dht_server.cc:672
    3. torrent::DhtServer::receive_timeout() libtorrent/src/dht/dht_server.cc:899
    4. std::tr1::_Mem_fn<void (torrent::DhtServer::*)()>::operator()(torrent::DhtServer*) const /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/g++-v4/tr1/functional:585
    5. std::tr1::result_of<std::tr1::_Mem_fn<void (torrent::DhtServer::*)()> (std::tr1::result_of<std::tr1::_Mu<torrent::DhtServer*, false, false> (torrent::DhtServer*,
    std::tr1::tuple<>)>::type)>::type std::tr1::_Bind<std::tr1::_Mem_fn<void (torrent::DhtServer::*)()> (torrent::DhtServer*)>::__call<, 0>(std::tr1::tuple<> const&,
    std::tr1::_Index_tuple<0>) /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/g++-v4/tr1/functional:1178
    6. std::tr1::result_of<std::tr1::_Mem_fn<void (torrent::DhtServer::*)()> (std::tr1::result_of<std::tr1::_Mu<torrent::DhtServer*, false, false> (torrent::DhtServer*,
    std::tr1::tuple<>)>::type)>::type std::tr1::_Bind<std::tr1::_Mem_fn<void (torrent::DhtServer::*)()> (torrent::DhtServer*)>::operator()<>()
    (/usr/lib64/libtorrent.so.19+0x2e1e5d)
    7. std::tr1::_Function_handler<void (), std::tr1::_Bind<std::tr1::_Mem_fn<void (torrent::DhtServer::*)()> (torrent::DhtServer*)> >::_M_invoke(std::tr1::_Any_data const&) /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/g++-v4/tr1/functional:1796
    8. std::tr1::function<void ()>::operator()() const (/usr/bin/rtorrent+0xa7b7b)
    9. torrent::thread_main::call_events() libtorrent/src/thread_main.cc:82
    10. torrent::thread_base::event_loop(torrent::thread_base*) libtorrent/src/torrent/utils/thread_base.cc:141
    11. main rtorrent/src/main.cc:867
    12. __libc_start_main (/lib64/libc.so.6+0x20733)
    13. _start (/usr/bin/rtorrent+0x9bce8)
    856d9ca8