glaze: crash with the main: heap-buffer-overflow (2023-05-16)

Hi Dear Author

I experienced with a a crash (heap-buffer-overflow) with my production app, I updated with the latest main, it still crash at some points, I fortunately catch the crash point with the debug version, followed with the backtrace. Original crash capture was followed too. I need your URGENT analysis, many many thanks!

The crash point is /home/swei/quant/trade/core/include/glaze/util/dump.hpp:38:16

which is comment with “HERE HERE …”, if (ix == b.size()) [[unlikely]] should be if (ix >= b.size()) [[unlikely]] ?

// Glaze Library
// For the license information refer to glaze.hpp

#pragma once

#include <span>

#include "glaze/core/write.hpp"
// #include <bit>

namespace glz::detail
{
   GLZ_ALWAYS_INLINE void dump(const char c, vector_like auto& b, auto&& ix) noexcept
   {
      if (ix == b.size()) [[unlikely]] {
         b.resize(b.size() * 2);
      }

      b[ix] = c;
      ++ix;
   }

   GLZ_ALWAYS_INLINE void dump(const char c, char*& b) noexcept
   {
      *b = c;
      ++b;
   }

   template <char c>
   GLZ_ALWAYS_INLINE void dump(vector_like auto& b, auto&& ix) noexcept
   {
      if (ix == b.size()) [[unlikely]] {
         b.resize(b.size() * 2);
      }

      using V = std::decay_t<decltype(b[0])>;
      if constexpr (std::same_as<V, char>) {
         b[ix] = c; // <--- HERE HERE HERE HERE HERE HERE HERE HERE HERE
      }
      else {
         b[ix] = static_cast<V>(c);
      }
      ++ix;
   }
...

Backtrace

❯ llvm-symbolizer-16 --obj=./ctpd < list.txt
void glz::detail::dump<(char)44, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, unsigned long&>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, unsigned long&)
/home/swei/quant/trade/core/include/glaze/util/dump.hpp:38:16

auto void glz::detail::to_json<core::QuoteData>::op<glz::opts{10u, false, true, true, true, false, (char)32, (unsigned char)3, false, true}, core::QuoteData&, glz::context&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, unsigned long&>(core::QuoteData&, glz::context&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, unsigned long&)::'lambda'(auto)::operator()<std::integral_constant<unsigned long, 14ul>>(auto) const
/home/swei/quant/trade/core/include/glaze/json/write.hpp:679:22

auto auto glz::for_each<18ul, void glz::detail::to_json<core::QuoteData>::op<glz::opts{10u, false, true, true, true, false, (char)32, (unsigned char)3, false, true}, core::QuoteData&, glz::context&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, unsigned long&>(core::QuoteData&, glz::context&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, unsigned long&)::'lambda'(auto)>(core::QuoteData&)::'lambda'(auto&&...)::operator()<std::integral_constant<unsigned long, 0ul>, std::integral_constant<unsigned long, 1ul>, std::integral_constant<unsigned long, 2ul>, std::integral_constant<unsigned long, 3ul>, std::integral_constant<unsigned long, 4ul>, std::integral_constant<unsigned long, 5ul>, std::integral_constant<unsigned long, 6ul>, std::integral_constant<unsigned long, 7ul>, std::integral_constant<unsigned long, 8ul>, std::integral_constant<unsigned long, 9ul>, std::integral_constant<unsigned long, 10ul>, std::integral_constant<unsigned long, 11ul>, std::integral_constant<unsigned long, 12ul>, std::integral_constant<unsigned long, 13ul>, std::integral_constant<unsigned long, 14ul>, std::integral_constant<unsigned long, 15ul>, std::integral_constant<unsigned long, 16ul>, std::integral_constant<unsigned long, 17ul>>(auto&&...) const
/home/swei/quant/trade/core/include/glaze/util/for_each.hpp:30:47

decltype(auto) auto glz::indexer<void, 0ul, 1ul, 2ul, 3ul, 4ul, 5ul, 6ul, 7ul, 8ul, 9ul, 10ul, 11ul, 12ul, 13ul, 14ul, 15ul, 16ul, 17ul>(std::integer_sequence<unsigned long, 0ul, 1ul, 2ul, 3ul, 4ul, 5ul, 6ul, 7ul, 8ul, 9ul, 10ul, 11ul, 12ul, 13ul, 14ul, 15ul, 16ul, 17ul>)::'lambda'(auto&&)::operator()<auto glz::for_each<18ul, void glz::detail::to_json<core::QuoteData>::op<glz::opts{10u, false, true, true, true, false, (char)32, (unsigned char)3, false, true}, core::QuoteData&, glz::context&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, unsigned long&>(core::QuoteData&, glz::context&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, unsigned long&)::'lambda'(auto)>(core::QuoteData&)::'lambda'(auto&&...)>(auto&&) const
/home/swei/quant/trade/core/include/glaze/util/for_each.hpp:14:17

auto glz::for_each<18ul, void glz::detail::to_json<core::QuoteData>::op<glz::opts{10u, false, true, true, true, false, (char)32, (unsigned char)3, false, true}, core::QuoteData&, glz::context&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, unsigned long&>(core::QuoteData&, glz::context&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, unsigned long&)::'lambda'(auto)>(core::QuoteData&)
/home/swei/quant/trade/core/include/glaze/util/for_each.hpp:30:14

void glz::detail::to_json<core::QuoteData>::op<glz::opts{10u, false, true, true, true, false, (char)32, (unsigned char)3, false, true}, core::QuoteData&, glz::context&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, unsigned long&>(core::QuoteData&, glz::context&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, unsigned long&)
/home/swei/quant/trade/core/include/glaze/json/write.hpp:643:13

void glz::detail::write<10u>::op<glz::opts{10u, false, true, true, true, false, (char)32, (unsigned char)3, false, true}, core::QuoteData&, glz::context&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, unsigned long&>(core::QuoteData&, glz::context&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, unsigned long&)
/home/swei/quant/trade/core/include/glaze/json/write.hpp:33:13

auto void glz::detail::to_json<core::rpc::request_t<core::QuoteData>>::op<glz::opts{10u, false, true, true, true, false, (char)32, (unsigned char)3, false, true}, core::rpc::request_t<core::QuoteData>&, glz::context&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, unsigned long&>(core::rpc::request_t<core::QuoteData>&, glz::context&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, unsigned long&)::'lambda'(auto)::operator()<std::integral_constant<unsigned long, 2ul>>(auto) const
/home/swei/quant/trade/core/include/glaze/json/write.hpp:714:19

auto auto glz::for_each<3ul, void glz::detail::to_json<core::rpc::request_t<core::QuoteData>>::op<glz::opts{10u, false, true, true, true, false, (char)32, (unsigned char)3, false, true}, core::rpc::request_t<core::QuoteData>&, glz::context&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, unsigned long&>(core::rpc::request_t<core::QuoteData>&, glz::context&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, unsigned long&)::'lambda'(auto)>(core::rpc::request_t<core::QuoteData>&)::'lambda'(auto&&...)::operator()<std::integral_constant<unsigned long, 0ul>, std::integral_constant<unsigned long, 1ul>, std::integral_constant<unsigned long, 2ul>>(auto&&...) const
/home/swei/quant/trade/core/include/glaze/util/for_each.hpp:30:47

decltype(auto) auto glz::indexer<void, 0ul, 1ul, 2ul>(std::integer_sequence<unsigned long, 0ul, 1ul, 2ul>)::'lambda'(auto&&)::operator()<auto glz::for_each<3ul, void glz::detail::to_json<core::rpc::request_t<core::QuoteData>>::op<glz::opts{10u, false, true, true, true, false, (char)32, (unsigned char)3, false, true}, core::rpc::request_t<core::QuoteData>&, glz::context&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, unsigned long&>(core::rpc::request_t<core::QuoteData>&, glz::context&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, unsigned long&)::'lambda'(auto)>(core::rpc::request_t<core::QuoteData>&)::'lambda'(auto&&...)>(auto&&) const
/home/swei/quant/trade/core/include/glaze/util/for_each.hpp:14:17

auto glz::for_each<3ul, void glz::detail::to_json<core::rpc::request_t<core::QuoteData>>::op<glz::opts{10u, false, true, true, true, false, (char)32, (unsigned char)3, false, true}, core::rpc::request_t<core::QuoteData>&, glz::context&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, unsigned long&>(core::rpc::request_t<core::QuoteData>&, glz::context&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, unsigned long&)::'lambda'(auto)>(core::rpc::request_t<core::QuoteData>&)
/home/swei/quant/trade/core/include/glaze/util/for_each.hpp:30:14

void glz::detail::to_json<core::rpc::request_t<core::QuoteData>>::op<glz::opts{10u, false, true, true, true, false, (char)32, (unsigned char)3, false, true}, core::rpc::request_t<core::QuoteData>&, glz::context&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, unsigned long&>(core::rpc::request_t<core::QuoteData>&, glz::context&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, unsigned long&)
/home/swei/quant/trade/core/include/glaze/json/write.hpp:643:13

void glz::detail::write<10u>::op<glz::opts{10u, false, true, true, true, false, (char)32, (unsigned char)3, false, true}, core::rpc::request_t<core::QuoteData>&, glz::context&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, unsigned long&>(core::rpc::request_t<core::QuoteData>&, glz::context&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, unsigned long&)
/home/swei/quant/trade/core/include/glaze/json/write.hpp:33:13

void glz::write<glz::opts{10u, false, true, true, true, false, (char)32, (unsigned char)3, false, true}, core::rpc::request_t<core::QuoteData>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, glz::context&>(core::rpc::request_t<core::QuoteData>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, glz::context&)
/home/swei/quant/trade/core/include/glaze/core/write.hpp:40:7

void glz::write<glz::opts{10u, false, true, true, true, false, (char)32, (unsigned char)3, false, true}, core::rpc::request_t<core::QuoteData>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>(core::rpc::request_t<core::QuoteData>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&)
/home/swei/quant/trade/core/include/glaze/core/write.hpp:50:7

std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>& json::write<core::rpc::request_t<core::QuoteData>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>(core::rpc::request_t<core::QuoteData>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&)
/home/swei/quant/trade/core/include/core/json.hpp:81:5

DataHub::send_quote(core::Pod&)
/home/swei/quant/trade/core/src/datahub.cpp:156:5

DataHub::process(core::Pod&)
/home/swei/quant/trade/core/src/datahub.cpp:132:9

DataHub::main()
/home/swei/quant/trade/core/src/datahub.cpp:115:13

core::DataHub::DataHub()::$_0::operator()() const
/home/swei/quant/trade/core/src/datahub.cpp:197:45

void std::__invoke_impl<void, core::DataHub::DataHub()::$_0>(std::__invoke_other, core::DataHub::DataHub()::$_0&&)
/usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/invoke.h:61:14

std::__invoke_result<core::DataHub::DataHub()::$_0>::type std::__invoke<core::DataHub::DataHub()::$_0>(core::DataHub::DataHub()::$_0&&)
/usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/invoke.h:96:14

void std::thread::_Invoker<std::tuple<core::DataHub::DataHub()::$_0>>::_M_invoke<0ul>(std::_Index_tuple<0ul>)
/usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/std_thread.h:253:13

std::thread::_Invoker<std::tuple<core::DataHub::DataHub()::$_0>>::operator()()
/usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/std_thread.h:260:11

std::thread::_State_impl<std::thread::_Invoker<std::tuple<core::DataHub::DataHub()::$_0>>>::_M_run()
/usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/std_thread.h:211:13

Address Sanitizer

=================================================================
==92950==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6120004f0ac1 at pc 0x56167e3da82b bp 0x7f0d9b9fe030 sp 0x7f0d9b9fe028
WRITE of size 1 at 0x6120004f0ac1 thread T1
==92950==WARNING: invalid path to external symbolizer!
==92950==WARNING: Failed to use and restart external symbolizer!
    #0 0x56167e3da82a  (/usr/bin/ctpd+0x4e282a) (BuildId: e26b4f3892f91348c4890ae5473094cd3ab7c081)
    #1 0x56167e78f166  (/usr/bin/ctpd+0x897166) (BuildId: e26b4f3892f91348c4890ae5473094cd3ab7c081)
    #2 0x56167e78c727  (/usr/bin/ctpd+0x894727) (BuildId: e26b4f3892f91348c4890ae5473094cd3ab7c081)
    #3 0x56167e78c2df  (/usr/bin/ctpd+0x8942df) (BuildId: e26b4f3892f91348c4890ae5473094cd3ab7c081)
    #4 0x56167e78bfa9  (/usr/bin/ctpd+0x893fa9) (BuildId: e26b4f3892f91348c4890ae5473094cd3ab7c081)
    #5 0x56167e78bde6  (/usr/bin/ctpd+0x893de6) (BuildId: e26b4f3892f91348c4890ae5473094cd3ab7c081)
    #6 0x56167e78bacc  (/usr/bin/ctpd+0x893acc) (BuildId: e26b4f3892f91348c4890ae5473094cd3ab7c081)
    #7 0x56167e78af6f  (/usr/bin/ctpd+0x892f6f) (BuildId: e26b4f3892f91348c4890ae5473094cd3ab7c081)
    #8 0x56167e78a6d9  (/usr/bin/ctpd+0x8926d9) (BuildId: e26b4f3892f91348c4890ae5473094cd3ab7c081)
    #9 0x56167e78a5b6  (/usr/bin/ctpd+0x8925b6) (BuildId: e26b4f3892f91348c4890ae5473094cd3ab7c081)
    #10 0x56167e78a449  (/usr/bin/ctpd+0x892449) (BuildId: e26b4f3892f91348c4890ae5473094cd3ab7c081)
    #11 0x56167e78a286  (/usr/bin/ctpd+0x892286) (BuildId: e26b4f3892f91348c4890ae5473094cd3ab7c081)
    #12 0x56167e789fdc  (/usr/bin/ctpd+0x891fdc) (BuildId: e26b4f3892f91348c4890ae5473094cd3ab7c081)
    #13 0x56167e789f01  (/usr/bin/ctpd+0x891f01) (BuildId: e26b4f3892f91348c4890ae5473094cd3ab7c081)
    #14 0x56167e789d4b  (/usr/bin/ctpd+0x891d4b) (BuildId: e26b4f3892f91348c4890ae5473094cd3ab7c081)
    #15 0x56167e7838ec  (/usr/bin/ctpd+0x88b8ec) (BuildId: e26b4f3892f91348c4890ae5473094cd3ab7c081)
    #16 0x56167e7811a3  (/usr/bin/ctpd+0x8891a3) (BuildId: e26b4f3892f91348c4890ae5473094cd3ab7c081)
    #17 0x56167e780f4a  (/usr/bin/ctpd+0x888f4a) (BuildId: e26b4f3892f91348c4890ae5473094cd3ab7c081)
    #18 0x56167e780cad  (/usr/bin/ctpd+0x888cad) (BuildId: e26b4f3892f91348c4890ae5473094cd3ab7c081)
    #19 0x56167e7832d6  (/usr/bin/ctpd+0x88b2d6) (BuildId: e26b4f3892f91348c4890ae5473094cd3ab7c081)
    #20 0x56167e783264  (/usr/bin/ctpd+0x88b264) (BuildId: e26b4f3892f91348c4890ae5473094cd3ab7c081)
    #21 0x56167e783224  (/usr/bin/ctpd+0x88b224) (BuildId: e26b4f3892f91348c4890ae5473094cd3ab7c081)
    #22 0x56167e7831fc  (/usr/bin/ctpd+0x88b1fc) (BuildId: e26b4f3892f91348c4890ae5473094cd3ab7c081)
    #23 0x56167e7831d4  (/usr/bin/ctpd+0x88b1d4) (BuildId: e26b4f3892f91348c4890ae5473094cd3ab7c081)
    #24 0x56167e783158  (/usr/bin/ctpd+0x88b158) (BuildId: e26b4f3892f91348c4890ae5473094cd3ab7c081)
    #25 0x7f0d9e6b22b2  (/lib/x86_64-linux-gnu/libstdc++.so.6+0xdc2b2) (BuildId: f57e02bfadacc0c923c82457d5e18e1830b5faea)
    #26 0x7f0d9e442b42  (/lib/x86_64-linux-gnu/libc.so.6+0x94b42) (BuildId: 69389d485a9793dbe873f0ea2c93e02efaa9aa3d)
    #27 0x7f0d9e4d49ff  (/lib/x86_64-linux-gnu/libc.so.6+0x1269ff) (BuildId: 69389d485a9793dbe873f0ea2c93e02efaa9aa3d)

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 19 (9 by maintainers)

Most upvoted comments

Hi I updated to the latest main (today: 2023-07-19) in order to solve prettify-indentation and empty std::set issue, but I still make the changes to ensure I will not potentially crash at this points, thanks for your great efforts!!!

if both ix == 0 && b.size() == 0?

diff --git a/include/glaze/util/dump.hpp b/include/glaze/util/dump.hpp
index 3f01592..857a6ad 100644
--- a/include/glaze/util/dump.hpp
+++ b/include/glaze/util/dump.hpp
@@ -12,8 +12,8 @@ namespace glz::detail
 {
    GLZ_ALWAYS_INLINE void dump(const char c, vector_like auto& b, auto&& ix) noexcept
    {
-      if (ix == b.size()) [[unlikely]] {
-         b.resize(b.size() * 2);
+      if (ix + 1 > b.size()) [[unlikely]] {
+         b.resize((ix + 1) * 2);
       }

       b[ix] = c;
@@ -29,8 +29,8 @@ namespace glz::detail
    template <char c>
    GLZ_ALWAYS_INLINE void dump(vector_like auto& b, auto&& ix) noexcept
    {
-      if (ix == b.size()) [[unlikely]] {
-         b.resize(b.size() * 2);
+      if (ix + 1 > b.size()) [[unlikely]] {
+         b.resize((ix + 1) * 2);
       }

       using V = std::decay_t<decltype(b[0])>;