OpenWebTorrent / openwebtorrent-tracker

Fast and simple Webtorrent tracker implementation in C++
https://openwebtorrent.com
71 stars 22 forks source link

Server crash due to illegal memory access #19

Closed theawless closed 3 years ago

theawless commented 3 years ago

Sometimes when a connection closes, there's invalid memory access which brings down the whole server.

I was able to 100% reproduce the error by sending a payload greater than the defined WebSocket max payload size. I have produced the following stack trace using gdb:

Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50      ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007ffffefe5859 in __GI_abort () at abort.c:79
#2  0x00007fffff28e911 in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#3  0x00007fffff29a38c in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#4  0x00007fffff29a3f7 in std::terminate() () from /lib/x86_64-linux-gnu/libstdc++.so.6
#5  0x00007fffff29a6a9 in __cxa_throw () from /lib/x86_64-linux-gnu/libstdc++.so.6
#6  0x00007fffff28e522 in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#7  0x00000000080576c9 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*> (
    this=0x7ffffffecaf0, __beg=0x20001 <error: Cannot access memory at address 0x20001>,
    __end=0x1000000020001 <error: Cannot access memory at address 0x1000000020001>) at /usr/include/c++/9/bits/basic_string.tcc:219
#8  0x000000000801dbcf in owt::FastTracker::disconnectPeer (this=0x8167a40, peer=0x81f2750)
    at /mnt/d/Projects/openwebtorrent-tracker/src/FastTracker.h:72
#9  0x000000000802380d in owt::WebtorrentTracker::onClose (this=0x7ffffffedc30, ws=0x81f26a0, code=1006, message="Received too big message")
    at /mnt/d/Projects/openwebtorrent-tracker/src/WebtorrentTracker.h:186
#10 0x0000000008021f05 in owt::WebtorrentTracker::run(int)::{lambda(auto:1*, int, std::basic_string_view<char, std::char_traits<char> >)#6}::operator()<uWS::WebSocket<true, true> >(uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> >) const (
    __closure=0x81953f0, ws=0x81f26a0, code=1006, message="Received too big message")
    at /mnt/d/Projects/openwebtorrent-tracker/src/WebtorrentTracker.h:98
#11 0x0000000008093598 in fu2::abi_400::detail::invocation::invoke<owt::WebtorrentTracker::run(int)::{lambda(auto:1*, int, std::basic_string_view<char, std::char_traits<char> >)#6}&, uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> > >(owt::WebtorrentTracker::run(int)::{lambda(auto:1*, int, std::basic_string_view<char, std::char_traits<char> >)#6}&, (uWS::WebSocket<true, true>*&&)...) (callable=...)
    at /mnt/d/Projects/openwebtorrent-tracker/deps/uWebSockets/src/f2/function2.hpp:184
#12 0x00000000080861ff in fu2::abi_400::detail::type_erasure::invocation_table::function_trait<void (uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> >)>::internal_invoker<fu2::abi_400::detail::type_erasure::box<false, owt::WebtorrentTracker::run(int)::{lambda(auto:1*, int, std::basic_string_view<char, std::char_traits<char> >)#6}, std::allocator<{lambda(auto:1*, int, std::basic_string_view<char, std::char_traits<char> >)#6}> >, true>::invoke(fu2::abi_400::detail::type_erasure::data_accessor*, unsigned long, uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> >) (data=0x81953f0, capacity=16, args#0=0x81f26a0, args#1=1006, args#2="Received too big message")
    at /mnt/d/Projects/openwebtorrent-tracker/deps/uWebSockets/src/f2/function2.hpp:587
#13 0x000000000803d69f in fu2::abi_400::detail::type_erasure::tables::vtable<fu2::abi_400::detail::property<true, false, void (uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> >)> >::invoke<0ul, fu2::abi_400::detail::type_erasure::data_accessor*, unsigned long const&, uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> > >(fu2::abi_400::detail::type_erasure::data_accessor*&&, unsigned long const&, uWS::WebSocket<true, true>*&&, int&&, std::basic_string_view<char, std::char_traits<char> >&&) const (this=0x8195400)
    at /mnt/d/Projects/openwebtorrent-tracker/deps/uWebSockets/src/f2/function2.hpp:995
#14 0x000000000803d752 in fu2::abi_400::detail::type_erasure::erasure<true, fu2::abi_400::detail::config<true, false, fu2::capacity_default>, fu2::abi_400::detail::property<true, false, void (uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> >)> >::invoke<0ul, fu2::abi_400::detail::type_erasure::erasure<true, fu2::abi_400::detail::config<true, false, fu2::capacity_default>, fu2::abi_400::detail::property<--Type <RET> for more, q to quit, c to continue without paging--
true, false, void (uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> >)> >&, uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> > >(fu2::abi_400::detail::type_erasure::erasure<true, fu2::abi_400::detail::config<true, false, fu2::capacity_default>, fu2::abi_400::detail::property<true, false, void (uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> >)> >&, uWS::WebSocket<true, true>*&&, int&&, std::basic_string_view<char, std::char_traits<char> >&&) (erasure=...)
    at /mnt/d/Projects/openwebtorrent-tracker/deps/uWebSockets/src/f2/function2.hpp:1215
#15 0x000000000803d7e6 in fu2::abi_400::detail::type_erasure::invocation_table::operator_impl<0ul, fu2::abi_400::detail::function<fu2::abi_400::detail::config<true, false, fu2::capacity_default>, fu2::abi_400::detail::property<true, false, void (uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> >)> >, void (uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> >)>::operator()(uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> >) (this=0x81953f0, args#0=0x81f26a0, args#1=1006,
    args#2="Received too big message") at /mnt/d/Projects/openwebtorrent-tracker/deps/uWebSockets/src/f2/function2.hpp:775
#16 0x000000000802dfe1 in uWS::TemplatedApp<true>::ws<owt::PeerContext>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, uWS::TemplatedApp<true>::WebSocketBehavior&&)::{lambda(uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> >)#1}::operator()(uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> >) (this=0x81953f0, ws=0x81f26a0, code=1006,
    message="Received too big message") at /mnt/d/Projects/openwebtorrent-tracker/deps/uWebSockets/src/App.h:171
#17 0x00000000080a9430 in fu2::abi_400::detail::invocation::invoke<uWS::TemplatedApp<true>::ws<owt::PeerContext>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, uWS::TemplatedApp<true>::WebSocketBehavior&&)::{lambda(uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> >)#1}&, uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> > >(uWS::TemplatedApp<true>::ws<owt::PeerContext>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, uWS::TemplatedApp<true>::WebSocketBehavior&&)::{lambda(uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> >)#1}&, (uWS::TemplatedApp<true>::ws<owt::PeerContext>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, uWS::TemplatedApp<true>::WebSocketBehavior&&)::{lambda(uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> >)#1}&)...) (callable=...)
    at /mnt/d/Projects/openwebtorrent-tracker/deps/uWebSockets/src/f2/function2.hpp:184
#18 0x000000000809f32a in fu2::abi_400::detail::type_erasure::invocation_table::function_trait<void (uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> >)>::internal_invoker<fu2::abi_400::detail::type_erasure::box<false, uWS::TemplatedApp<true>::ws<owt::PeerContext>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, uWS::TemplatedApp<true>::WebSocketBehavior&&)::{lambda(uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> >)#1}, std::allocator<{lambda(uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> >)#1}> >, false>::invoke(fu2::abi_400::detail::type_erasure::data_accessor*, unsigned long, uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> >) (data=0x8196260, capacity=16, args#0=0x81f26a0, args#1=1006,
    args#2="Received too big message") at /mnt/d/Projects/openwebtorrent-tracker/deps/uWebSockets/src/f2/function2.hpp:587
#19 0x000000000803d69f in fu2::abi_400::detail::type_erasure::tables::vtable<fu2::abi_400::detail::property<true, false, void (uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> >)> >::invoke<0ul, fu2::abi_400::detail::type_erasure::data_accessor*, unsigned long const&, uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> > >(fu2::abi_400::detail::type_erasure::data_accessor*&&, unsigned long const&, uWS::WebSocket<true, true>*&&, int&&, std::basic_string_view<char, std::char_traits<char> >&&) const (this=0x8196270)
    at /mnt/d/Projects/openwebtorrent-tracker/deps/uWebSockets/src/f2/function2.hpp:995
#20 0x000000000803d752 in fu2::abi_400::detail::type_erasure::erasure<true, fu2::abi_400::detail::config<true, false, fu2::capacity_default>, fu2::abi_400::detail::property<true, false, void (uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> >)> >::invoke<0ul,--Type <RET> for more, q to quit, c to continue without paging--
 fu2::abi_400::detail::type_erasure::erasure<true, fu2::abi_400::detail::config<true, false, fu2::capacity_default>, fu2::abi_400::detail::property<true, false, void (uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> >)> >&, uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> > >(fu2::abi_400::detail::type_erasure::erasure<true, fu2::abi_400::detail::config<true, false, fu2::capacity_default>, fu2::abi_400::detail::property<true, false, void (uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> >)> >&, uWS::WebSocket<true, true>*&&, int&&, std::basic_string_view<char, std::char_traits<char> >&&) (erasure=...)
    at /mnt/d/Projects/openwebtorrent-tracker/deps/uWebSockets/src/f2/function2.hpp:1215
#21 0x000000000803d7e6 in fu2::abi_400::detail::type_erasure::invocation_table::operator_impl<0ul, fu2::abi_400::detail::function<fu2::abi_400::detail::config<true, false, fu2::capacity_default>, fu2::abi_400::detail::property<true, false, void (uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> >)> >, void (uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> >)>::operator()(uWS::WebSocket<true, true>*, int, std::basic_string_view<char, std::char_traits<char> >) (this=0x8196260, args#0=0x81f26a0, args#1=1006,
    args#2="Received too big message") at /mnt/d/Projects/openwebtorrent-tracker/deps/uWebSockets/src/f2/function2.hpp:775
#22 0x0000000008054cc6 in uWS::WebSocketContext<true, true>::init()::{lambda(auto:1*, int, void*)#1}::operator()<us_socket_t>(us_socket_t*, int, void*) const (this=0x0, s=0x81f26a0, code=24, reason=0x80ea9d2) at /mnt/d/Projects/openwebtorrent-tracker/deps/uWebSockets/src/WebSocketContext.h:248
#23 0x0000000008079858 in uWS::WebSocketContext<true, true>::init()::{lambda(auto:1*, int, void*)#1}::_FUN<us_socket_t>(us_socket_t*, int, void*)
    () at /mnt/d/Projects/openwebtorrent-tracker/deps/uWebSockets/src/WebSocketContext.h:240
#24 0x00000000080d36d5 in ssl_on_close (s=0x81f26a0, code=24, reason=0x80ea9d2)
    at /mnt/d/Projects/openwebtorrent-tracker/deps/uWebSockets/uSockets/src/crypto/openssl.c:182
#25 0x00000000080d612f in us_socket_close (ssl=1, s=0x81f26a0, code=24, reason=0x80ea9d2)
    at /mnt/d/Projects/openwebtorrent-tracker/deps/uWebSockets/uSockets/src/socket.c:71
#26 0x0000000008066fbd in uWS::WebSocketContext<true, true>::forceClose (wState=0x81f2700, s=0x81f26a0, reason="Received too big message")
    at /mnt/d/Projects/openwebtorrent-tracker/deps/uWebSockets/src/WebSocketContext.h:56
#27 0x0000000008086bd2 in uWS::WebSocketContext<true, true>::handleFragment (
    data=0x7ffffed30054 "5ac9c1424693de30593ac710f3a646afb0663b3855e419320288e30f4f8235806ee5967e2f1606db6dd2c698799317dd67849cd1cd7ace464090f91fdefbcd9835a0444a140e46981e7d9b4a2619ff636f7acb948d6c78b4322943d7917f614d866c3119"..., length=16384, remainingBytes=0, opCode=1, fin=false,
    webSocketState=0x81f2700, s=0x81f26a0) at /mnt/d/Projects/openwebtorrent-tracker/deps/uWebSockets/src/WebSocketContext.h:105
#28 0x0000000008079ff6 in uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true> >::consumeMessage<8u, unsigned short> (payLength=16384,
    src=@0x7ffffffed2e8: 0x7ffffed30050 "", length=@0x7ffffffed2e4: 23613, wState=0x81f2700, user=0x81f26a0)
    at /mnt/d/Projects/openwebtorrent-tracker/deps/uWebSockets/src/WebSocketProtocol.h:328
#29 0x0000000008066e5b in uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true> >::consume (src=0x7ffffed30050 "", length=23613,
    wState=0x81f2700, user=0x81f26a0) at /mnt/d/Projects/openwebtorrent-tracker/deps/uWebSockets/src/WebSocketProtocol.h:430
#30 0x0000000008054e00 in uWS::WebSocketContext<true, true>::init()::{lambda(auto:1*, char*, int)#2}::operator()<us_socket_t>(us_socket_t*, char*, int) const (this=0x0, s=0x81f26a0, data=0x7ffffed20030 "\001\376@", length=89181)
    at /mnt/d/Projects/openwebtorrent-tracker/deps/uWebSockets/src/WebSocketContext.h:285
#31 0x000000000807a90d in uWS::WebSocketContext<true, true>::init()::{lambda(auto:1*, char*, int)#2}::_FUN<us_socket_t>(us_socket_t*, char*, int)
    () at /mnt/d/Projects/openwebtorrent-tracker/deps/uWebSockets/src/WebSocketContext.h:264
#32 0x00000000080d38fa in ssl_on_data (s=0x81f26a0, data=0x7ffffedb0030, length=89313)
--Type <RET> for more, q to quit, c to continue without paging--
    at /mnt/d/Projects/openwebtorrent-tracker/deps/uWebSockets/uSockets/src/crypto/openssl.c:265
#33 0x00000000080d5cf0 in us_internal_dispatch_ready_poll (p=0x81f26a0, error=0, events=1)