Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ASAN error while parsing BJData (Heap-buffer-overflow READ 1) #3492

Closed
2 tasks done
nlohmann opened this issue May 12, 2022 · 9 comments · Fixed by #3500
Closed
2 tasks done

ASAN error while parsing BJData (Heap-buffer-overflow READ 1) #3492

nlohmann opened this issue May 12, 2022 · 9 comments · Fixed by #3500
Assignees
Labels
aspect: binary formats BSON, CBOR, MessagePack, UBJSON confirmed kind: bug release item: 🐛 bug fix solution: proposed fix a fix for the issue has been proposed and waits for confirmation

Comments

@nlohmann
Copy link
Owner

Description

OSS-Fuzz reports a buffer overflow when fuzzing with ASAN

Reproduction steps

Expected vs. actual results

Expected: parse error or valid JSON value returned

Actual: ASAN runtime error

Minimal code example

No response

Error messages

+----------------------------------------Release Build Stacktrace----------------------------------------+
Command: /mnt/scratch0/clusterfuzz/resources/platform/linux/unshare -c -n /mnt/scratch0/clusterfuzz/bot/builds/clusterfuzz-builds_json_26b1464c0c18fac23c49bf26ed996090f90e682a/revisions/parse_bjdata_fuzzer -rss_limit_mb=2560 -timeout=60 -runs=100 /mnt/scratch0/clusterfuzz/bot/inputs/fuzzer-testcases/crash-9c5801955f5d26b496b0a3a159e11fc8baa926bf
Time ran: 0.3587803840637207
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 937550358
INFO: Loaded 1 modules   (6059 inline 8-bit counters): 6059 [0x694960, 0x69610b),
INFO: Loaded 1 PC tables (6059 PCs): 6059 [0x624770,0x63c220),
/mnt/scratch0/clusterfuzz/bot/builds/clusterfuzz-builds_json_26b1464c0c18fac23c49bf26ed996090f90e682a/revisions/parse_bjdata_fuzzer: Running 1 inputs 100 time(s) each.
Running: /mnt/scratch0/clusterfuzz/bot/inputs/fuzzer-testcases/crash-9c5801955f5d26b496b0a3a159e11fc8baa926bf
=================================================================
==101886==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000140 at pc 0x000000576031 bp 0x7ffcb2e4ef80 sp 0x7ffcb2e4ef78
READ of size 1 at 0x602000000140 thread T0
SCARINESS: 22 (1-byte-read-heap-buffer-overflow-far-from-bounds)
    #0 0x576030 in __is_long /usr/local/include/c++/v1/string:1445:39
    #1 0x576030 in __get_pointer /usr/local/include/c++/v1/string:1539:17
    #2 0x576030 in data /usr/local/include/c++/v1/string:1251:75
    #3 0x576030 in operator basic_string_view /usr/local/include/c++/v1/string:889:65
    #4 0x576030 in compare /usr/local/include/c++/v1/string:3914:32
    #5 0x576030 in operator<<char, std::__1::char_traits<char>, std::__1::allocator<char> > /usr/local/include/c++/v1/string:4141:18
    #6 0x576030 in operator() /usr/local/include/c++/v1/__functional/operations.h:487:21
    #7 0x576030 in operator() /usr/local/include/c++/v1/map:537:17
    #8 0x576030 in std::__1::__tree_node_base<void*>*& std::__1::__tree<std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >, std::__1::__map_value_compare<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, true>, std::__1::allocator<std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > > >::__find_equal<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::__tree_end_node<std::__1::__tree_node_base<void*>*>*&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) /usr/local/include/c++/v1/__tree:1977:17
    #9 0x5756a1 in std::__1::pair<std::__1::__tree_iterator<std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >, std::__1::__tree_node<std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >, void*>*, long>, bool> std::__1::__tree<std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >, std::__1::__map_value_compare<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, true>, std::__1::allocator<std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > > >::__emplace_unique_key_args<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::piecewise_construct_t const&, std::__1::tuple<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&>, std::__1::tuple<> >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::piecewise_construct_t const&, std::__1::tuple<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&>&&, std::__1::tuple<>&&) /usr/local/include/c++/v1/__tree:2093:36
    #10 0x59e32c in operator[] /usr/local/include/c++/v1/map:1546:20
    #11 0x59e32c in key json/single_include/nlohmann/json.hpp:6234:62
    #12 0x59e32c in nlohmann::detail::binary_reader<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::detail::iterator_input_adapter<std::__1::__wrap_iter<unsigned char const*> >, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >::get_ubjson_object() json/single_include/nlohmann/json.hpp:11062:21
    #13 0x591184 in nlohmann::detail::binary_reader<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::detail::iterator_input_adapter<std::__1::__wrap_iter<unsigned char const*> >, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >::get_ubjson_value(int) json/single_include/nlohmann/json.hpp:10878:24
    #14 0x562df4 in parse_ubjson_internal json/single_include/nlohmann/json.hpp:10299:16
    #15 0x562df4 in nlohmann::detail::binary_reader<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::detail::iterator_input_adapter<std::__1::__wrap_iter<unsigned char const*> >, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >::sax_parse(nlohmann::detail::input_format_t, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >*, bool, nlohmann::detail::cbor_tag_handler_t) json/single_include/nlohmann/json.hpp:8597:26
    #16 0x55e91b in nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::from_bjdata<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&>(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&, bool, bool) json/single_include/nlohmann/json.hpp:22496:93
    #17 0x55d22c in LLVMFuzzerTestOneInput json/tests/src/fuzzer-parse_bjdata.cpp:40:19
    #18 0x455233 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:611:15
    #19 0x440ec2 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:324:6
    #20 0x44670c in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:860:9
    #21 0x46f302 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
    #22 0x7fa6c7d830b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/libc-start.c:308:16
    #23 0x41f6ed in _start
0x602000000140 is located 0 bytes to the right of 16-byte region [0x602000000130,0x602000000140)
freed by thread T0 here:
    #0 0x55b15d in operator delete(void*) /src/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp:152:3
    #1 0x580c8b in __libcpp_operator_delete<void *> /usr/local/include/c++/v1/new:255:3
    #2 0x580c8b in __do_deallocate_handle_size<> /usr/local/include/c++/v1/new:279:10
    #3 0x580c8b in __libcpp_deallocate /usr/local/include/c++/v1/new:289:12
    #4 0x580c8b in deallocate /usr/local/include/c++/v1/__memory/allocator.h:114:13
    #5 0x580c8b in deallocate /usr/local/include/c++/v1/__memory/allocator_traits.h:282:13
    #6 0x580c8b in ~__split_buffer /usr/local/include/c++/v1/__split_buffer:338:9
    #7 0x580c8b in void std::__1::vector<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, std::__1::allocator<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >::__emplace_back_slow_path<long&>(long&) /usr/local/include/c++/v1/vector:1679:1
    #8 0x5804ba in emplace_back<long &> /usr/local/include/c++/v1/vector:1696:9
    #9 0x5804ba in nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >* nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::handle_value<long&>(long&) json/single_include/nlohmann/json.hpp:6303:46
    #10 0x5a1b2b in number_integer json/single_include/nlohmann/json.hpp:6191:9
    #11 0x5a1b2b in nlohmann::detail::binary_reader<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::detail::iterator_input_adapter<std::__1::__wrap_iter<unsigned char const*> >, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >::get_ubjson_size_value(unsigned long&, bool&, int) json/single_include/nlohmann/json.hpp:10606:29
    #12 0x5a4c08 in nlohmann::detail::binary_reader<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::detail::iterator_input_adapter<std::__1::__wrap_iter<unsigned char const*> >, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >::get_ubjson_size_type(std::__1::pair<unsigned long, int>&) json/single_include/nlohmann/json.hpp:10692:29
    #13 0x5a3c8c in nlohmann::detail::binary_reader<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::detail::iterator_input_adapter<std::__1::__wrap_iter<unsigned char const*> >, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >::get_ubjson_ndarray_size(std::__1::vector<unsigned long, std::__1::allocator<unsigned long> >&) json/single_include/nlohmann/json.hpp:10417:13
    #14 0x5a0a33 in nlohmann::detail::binary_reader<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::detail::iterator_input_adapter<std::__1::__wrap_iter<unsigned char const*> >, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >::get_ubjson_size_value(unsigned long&, bool&, int) json/single_include/nlohmann/json.hpp:10586:21
    #15 0x5a4c08 in nlohmann::detail::binary_reader<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::detail::iterator_input_adapter<std::__1::__wrap_iter<unsigned char const*> >, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >::get_ubjson_size_type(std::__1::pair<unsigned long, int>&) json/single_include/nlohmann/json.hpp:10692:29
    #16 0x59d87e in nlohmann::detail::binary_reader<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::detail::iterator_input_adapter<std::__1::__wrap_iter<unsigned char const*> >, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >::get_ubjson_object() json/single_include/nlohmann/json.hpp:11001:13
    #17 0x591184 in nlohmann::detail::binary_reader<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::detail::iterator_input_adapter<std::__1::__wrap_iter<unsigned char const*> >, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >::get_ubjson_value(int) json/single_include/nlohmann/json.hpp:10878:24
    #18 0x59b35a in parse_ubjson_internal json/single_include/nlohmann/json.hpp:10299:16
    #19 0x59b35a in nlohmann::detail::binary_reader<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::detail::iterator_input_adapter<std::__1::__wrap_iter<unsigned char const*> >, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >::get_ubjson_array() json/single_include/nlohmann/json.hpp:10984:21
    #20 0x59116f in nlohmann::detail::binary_reader<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::detail::iterator_input_adapter<std::__1::__wrap_iter<unsigned char const*> >, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >::get_ubjson_value(int) json/single_include/nlohmann/json.hpp:10875:24
    #21 0x59e45e in parse_ubjson_internal json/single_include/nlohmann/json.hpp:10299:16
    #22 0x59e45e in nlohmann::detail::binary_reader<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::detail::iterator_input_adapter<std::__1::__wrap_iter<unsigned char const*> >, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >::get_ubjson_object() json/single_include/nlohmann/json.hpp:11066:21
    #23 0x591184 in nlohmann::detail::binary_reader<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::detail::iterator_input_adapter<std::__1::__wrap_iter<unsigned char const*> >, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >::get_ubjson_value(int) json/single_include/nlohmann/json.hpp:10878:24
    #24 0x562df4 in parse_ubjson_internal json/single_include/nlohmann/json.hpp:10299:16
    #25 0x562df4 in nlohmann::detail::binary_reader<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::detail::iterator_input_adapter<std::__1::__wrap_iter<unsigned char const*> >, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >::sax_parse(nlohmann::detail::input_format_t, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >*, bool, nlohmann::detail::cbor_tag_handler_t) json/single_include/nlohmann/json.hpp:8597:26
    #26 0x55e91b in nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::from_bjdata<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&>(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&, bool, bool) json/single_include/nlohmann/json.hpp:22496:93
    #27 0x55d22c in LLVMFuzzerTestOneInput json/tests/src/fuzzer-parse_bjdata.cpp:40:19
    #28 0x455233 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:611:15
    #29 0x440ec2 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:324:6
    #30 0x44670c in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:860:9
    #31 0x46f302 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
    #32 0x7fa6c7d830b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/libc-start.c:308:16
previously allocated by thread T0 here:
    #0 0x55a8fd in operator new(unsigned long) /src/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp:95:3
    #1 0x580a84 in __libcpp_operator_new<unsigned long> /usr/local/include/c++/v1/new:245:10
    #2 0x580a84 in __libcpp_allocate /usr/local/include/c++/v1/new:271:10
    #3 0x580a84 in allocate /usr/local/include/c++/v1/__memory/allocator.h:105:38
    #4 0x580a84 in allocate /usr/local/include/c++/v1/__memory/allocator_traits.h:262:20
    #5 0x580a84 in __split_buffer /usr/local/include/c++/v1/__split_buffer:306:29
    #6 0x580a84 in void std::__1::vector<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, std::__1::allocator<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >::__emplace_back_slow_path<long&>(long&) /usr/local/include/c++/v1/vector:1674:49
    #7 0x5804ba in emplace_back<long &> /usr/local/include/c++/v1/vector:1696:9
    #8 0x5804ba in nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >* nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::handle_value<long&>(long&) json/single_include/nlohmann/json.hpp:6303:46
    #9 0x5a1b2b in number_integer json/single_include/nlohmann/json.hpp:6191:9
    #10 0x5a1b2b in nlohmann::detail::binary_reader<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::detail::iterator_input_adapter<std::__1::__wrap_iter<unsigned char const*> >, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >::get_ubjson_size_value(unsigned long&, bool&, int) json/single_include/nlohmann/json.hpp:10606:29
    #11 0x5a4c08 in nlohmann::detail::binary_reader<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::detail::iterator_input_adapter<std::__1::__wrap_iter<unsigned char const*> >, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >::get_ubjson_size_type(std::__1::pair<unsigned long, int>&) json/single_include/nlohmann/json.hpp:10692:29
    #12 0x5a3c8c in nlohmann::detail::binary_reader<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::detail::iterator_input_adapter<std::__1::__wrap_iter<unsigned char const*> >, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >::get_ubjson_ndarray_size(std::__1::vector<unsigned long, std::__1::allocator<unsigned long> >&) json/single_include/nlohmann/json.hpp:10417:13
    #13 0x5a0a33 in nlohmann::detail::binary_reader<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::detail::iterator_input_adapter<std::__1::__wrap_iter<unsigned char const*> >, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >::get_ubjson_size_value(unsigned long&, bool&, int) json/single_include/nlohmann/json.hpp:10586:21
    #14 0x5a4c08 in nlohmann::detail::binary_reader<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::detail::iterator_input_adapter<std::__1::__wrap_iter<unsigned char const*> >, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >::get_ubjson_size_type(std::__1::pair<unsigned long, int>&) json/single_include/nlohmann/json.hpp:10692:29
    #15 0x59d87e in nlohmann::detail::binary_reader<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::detail::iterator_input_adapter<std::__1::__wrap_iter<unsigned char const*> >, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >::get_ubjson_object() json/single_include/nlohmann/json.hpp:11001:13
    #16 0x591184 in nlohmann::detail::binary_reader<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::detail::iterator_input_adapter<std::__1::__wrap_iter<unsigned char const*> >, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >::get_ubjson_value(int) json/single_include/nlohmann/json.hpp:10878:24
    #17 0x59b35a in parse_ubjson_internal json/single_include/nlohmann/json.hpp:10299:16
    #18 0x59b35a in nlohmann::detail::binary_reader<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::detail::iterator_input_adapter<std::__1::__wrap_iter<unsigned char const*> >, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >::get_ubjson_array() json/single_include/nlohmann/json.hpp:10984:21
    #19 0x59116f in nlohmann::detail::binary_reader<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::detail::iterator_input_adapter<std::__1::__wrap_iter<unsigned char const*> >, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >::get_ubjson_value(int) json/single_include/nlohmann/json.hpp:10875:24
    #20 0x59e45e in parse_ubjson_internal json/single_include/nlohmann/json.hpp:10299:16
    #21 0x59e45e in nlohmann::detail::binary_reader<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::detail::iterator_input_adapter<std::__1::__wrap_iter<unsigned char const*> >, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >::get_ubjson_object() json/single_include/nlohmann/json.hpp:11066:21
    #22 0x591184 in nlohmann::detail::binary_reader<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::detail::iterator_input_adapter<std::__1::__wrap_iter<unsigned char const*> >, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >::get_ubjson_value(int) json/single_include/nlohmann/json.hpp:10878:24
    #23 0x562df4 in parse_ubjson_internal json/single_include/nlohmann/json.hpp:10299:16
    #24 0x562df4 in nlohmann::detail::binary_reader<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::detail::iterator_input_adapter<std::__1::__wrap_iter<unsigned char const*> >, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >::sax_parse(nlohmann::detail::input_format_t, nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >*, bool, nlohmann::detail::cbor_tag_handler_t) json/single_include/nlohmann/json.hpp:8597:26
    #25 0x55e91b in nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::from_bjdata<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&>(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&, bool, bool) json/single_include/nlohmann/json.hpp:22496:93
    #26 0x55d22c in LLVMFuzzerTestOneInput json/tests/src/fuzzer-parse_bjdata.cpp:40:19
    #27 0x455233 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:611:15
    #28 0x440ec2 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:324:6
    #29 0x44670c in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:860:9
    #30 0x46f302 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
    #31 0x7fa6c7d830b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/libc-start.c:308:16
SUMMARY: AddressSanitizer: heap-buffer-overflow (/mnt/scratch0/clusterfuzz/bot/builds/clusterfuzz-builds_json_26b1464c0c18fac23c49bf26ed996090f90e682a/revisions/parse_bjdata_fuzzer+0x576030)
Shadow bytes around the buggy address:
  0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff8000: fa fa 00 00 fa fa 00 fa fa fa 00 fa fa fa 00 fa
  0x0c047fff8010: fa fa fd fa fa fa fd fd fa fa fd fa fa fa fd fd
=>0x0c047fff8020: fa fa 00 00 fa fa fd fd[fa]fa fa fa fa fa fa fa
  0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8070: fa fa fa fa fa fa fa fa fa fa fa fa 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
==101886==ABORTING

Compiler and operating system

OSS-Fuzz

Library version

develop

Validation

@nlohmann nlohmann added kind: bug aspect: binary formats BSON, CBOR, MessagePack, UBJSON labels May 12, 2022
@nlohmann
Copy link
Owner Author

FYI @fangq

@falbrechtskirchinger
Copy link
Contributor

falbrechtskirchinger commented May 12, 2022

Do you mind if I switch the make targets over to using the multi-header version? That would make the stack trace more informative. For example, single_include/nlohmann/json.hpp:10299:16 doesn't tell me anything at first glance.

And btw., the links you provide are inaccessible to us plebs. ;-)

Edit: I mean these two:
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=47391
https://oss-fuzz.com/testcase-detail/5698044521218048

I can download the testcase .zip.

@nlohmann
Copy link
Owner Author

Do you mind if I switch the make targets over to using the multi-header version? That would make the stack trace more informative. For example, single_include/nlohmann/json.hpp:10299:16 doesn't tell me anything at first glance.

Not at all - please go ahead!

And btw., the links you provide are inaccessible to us plebs. ;-)

I'll check what needs to be done for this - or whom to ask.

@fangq
Copy link
Contributor

fangq commented May 12, 2022

@nlohmann and @falbrechtskirchinger, I wonder if this is related to the handling of negative sizes as we touched upon in #3475 (comment)? does this only happen for BJData or also for UBJSON?

because a negative length is currently static_casted to a size_t, therefore, it can create huge buffer lengths, which can be a problem. I am wondering if you are ok to add a new parse error inside all signed-integer branches of get_ubjson_size_value, such as

case 'i':
{
std::int8_t number{};
if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
{
return false;
}
result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
return true;
}

where we can add a condition in

if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number) || number < 0 )){
    return false;
}

to discard this, or, more verbosely, for each signed integer

if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number))){
    return false;
}
if( number < 0){
    return sax->parse_error(chars_read, last_token, parse_error::create(???, chars_read,
                exception_message(input_format, "negative sizes are not permitted", "size"), nullptr));
}

what do you think?

@nlohmann
Copy link
Owner Author

I analyzed the issue, and just like #3490 (comment), it is caused by creating invalid SAX events.

These events are triggered:

<object>
    <key key="" />
    <array>
        <object size="3">
            <key key="_ArraySize_" />
            <array size="2">
                <number_integer val="32" />
                <number_integer val="0" />
            </array>
            <object size="0">   <!-- first error: expected a key here -->
            </object>
        </array>                <!-- second error: parsing an object, but closing an array -->
        <key key="" />
        <parse_error id="18" token="<end of file>" />

The parser must make sure that

  1. Key events must only occur in objects.
  2. Each value event in an object must be preceded by a key event.
  3. End events must match the previous open event.

These mismatched events yield undefined behavior in the SAX-DOM parser. In #3498 I propose adding assertions to make this undefined behavior visible. That PR does not fix this issue, but makes it clear that is unrelated to any sanitizer.

@fangq
Copy link
Contributor

fangq commented May 17, 2022

thanks @nlohmann, this is very helpful. I will look into this further.

going over the hex dump of the fuzzer data, I spotted a few issues:

00000000   7B 69 FF 5B  7B 23 5B 23  5B 55 20 55  00 5D 5D 55  00     |     {i.[{#[#[U U.]]U.

here are the issues, and some of my questions:

  1. I am curious why { i 0xFF translates to <object><key key="" /> ? is this expected? for signed integer i, 0xFF is -1, and I wonder if we should raise an error or make the output discarded whenever a negative length is encountered?
  2. for {#[#[U 0x20 U 0x00]], I expect this part of the code should raise a parser error - because BJData does not allow ND array #[ to be used for object size, but somehow this is not triggered
  3. from the SAX structure you posted for the last few bugs, it appears that the misaligned object/array keys are triggered when any of the ND array dimension is 0 (such as this case: [32, 0]), so, I will focus on detecting such input, and throw an error.

@nlohmann
Copy link
Owner Author

From https://json.nlohmann.me/features/parsing/sax_interface/:

// called when an object or array begins or ends, resp. The number of elements is passed (or -1 if not known)
bool start_object(std::size_t elements);

Passing -1 is not an error - it is interpreted as an unknown size. The BJData parser should raise an error in case of a negative length, because this is apparently nonsense as it does not mean unknown size there.

@fangq
Copy link
Contributor

fangq commented May 17, 2022

I see. although start_object(-1) has a well defined behavior, I believe either UBJSON or BJData parser should raise a parse_error when the count parameter is negative before passing it to start_object or start_array, because UBJSON spec requires count in an optimized container must be >=0, see

https://ubjson.org/type-reference/container-types/#optimized-format
https://github.com/NeuroJSON/bjdata/blob/Draft_2/Binary_JData_Specification.md#additional-rules

@nlohmann
Copy link
Owner Author

Exactly.

@nlohmann nlohmann added confirmed solution: proposed fix a fix for the issue has been proposed and waits for confirmation release item: 🐛 bug fix labels May 18, 2022
@nlohmann nlohmann self-assigned this May 18, 2022
@nlohmann nlohmann added this to the Release 3.11.0 milestone May 18, 2022
nlohmann pushed a commit that referenced this issue May 18, 2022
…3491,#3492,#3490) (#3500)

* Discard optimized containers with negative counts in UBJSON/BJData (#3491,#3492,#3490)

* fix msvc error

* update unit tests for negative sized containers

* use a loop to test 0 ndarray dimension

* throw an error when count is negative, merge CHECK_THROW_AS and _WITH with _WITH_AS
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
aspect: binary formats BSON, CBOR, MessagePack, UBJSON confirmed kind: bug release item: 🐛 bug fix solution: proposed fix a fix for the issue has been proposed and waits for confirmation
Projects
None yet
3 participants