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

UBSAN error while parsing BJData (Invalid-bool-value) #3490

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

UBSAN error while parsing BJData (Invalid-bool-value) #3490

nlohmann opened this issue May 12, 2022 · 3 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 runtime error: load of value 16, which is not a valid value for type 'bool' when fuzzing with UBSAN.

Reproduction steps

Expected vs. actual results

Expected: parse error or valid JSON value returned

Actual: UBSAN runtime error

Minimal code example

No response

Error messages

[Environment] UBSAN_OPTIONS=print_stacktrace=1:silence_unsigned_overflow=1
+----------------------------------------Release Build Stacktrace----------------------------------------+
Command: /mnt/scratch0/clusterfuzz/resources/platform/linux/unshare -c -n /mnt/scratch0/clusterfuzz/bot/builds/clusterfuzz-builds_json_3dc7f07cae4ab217c21b70d40f93a3acccc6b431/revisions/parse_bjdata_fuzzer -rss_limit_mb=2560 -timeout=60 -runs=100 /mnt/scratch0/clusterfuzz/bot/inputs/fuzzer-testcases/crash-fb1efa0b5e5f3aa16f32b3d68449242cabca995e
Time ran: 0.09805822372436523
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 3403573080
INFO: Loaded 1 modules   (5891 inline 8-bit counters): 5891 [0x5944d0, 0x595bd3),
INFO: Loaded 1 PC tables (5891 PCs): 5891 [0x530a68,0x547a98),
/mnt/scratch0/clusterfuzz/bot/builds/clusterfuzz-builds_json_3dc7f07cae4ab217c21b70d40f93a3acccc6b431/revisions/parse_bjdata_fuzzer: Running 1 inputs 100 time(s) each.
Running: /mnt/scratch0/clusterfuzz/bot/inputs/fuzzer-testcases/crash-fb1efa0b5e5f3aa16f32b3d68449242cabca995e
/usr/local/bin/../include/c++/v1/__tree:283:54: runtime error: load of value 16, which is not a valid value for type 'bool'
    #0 0x4bde0f in void std::__1::__tree_balance_after_insert<std::__1::__tree_node_base<void*>*>(std::__1::__tree_node_base<void*>*, std::__1::__tree_node_base<void*>*) /usr/local/include/c++/v1/__tree:283:54
    #1 0x4bd672 in 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> > > > > >::__insert_node_at(std::__1::__tree_end_node<std::__1::__tree_node_base<void*>*>*, std::__1::__tree_node_base<void*>*&, std::__1::__tree_node_base<void*>*) /usr/local/include/c++/v1/__tree:2083:5
    #2 0x4bd3ba 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:2099:9
    #3 0x4bd2f5 in std::__1::map<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> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, 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> > > > > >::operator[](std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) /usr/local/include/c++/v1/map:1546:20
    #4 0x4bcb15 in 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> > > >::key(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) json/single_include/nlohmann/json.hpp:6234:62
    #5 0x4c9e13 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
    #6 0x4c7095 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
    #7 0x4c9e40 in parse_ubjson_internal json/single_include/nlohmann/json.hpp:10299:16
    #8 0x4c9e40 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
    #9 0x4c7095 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
    #10 0x4b5a95 in parse_ubjson_internal json/single_include/nlohmann/json.hpp:10299:16
    #11 0x4b5a95 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
    #12 0x4b3b51 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
    #13 0x4b34bc in LLVMFuzzerTestOneInput json/tests/src/fuzzer-parse_bjdata.cpp:40:19
    #14 0x43d5b3 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:611:15
    #15 0x429242 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:324:6
    #16 0x42ea8c in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:860:9
    #17 0x457682 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
    #18 0x7f1129c5f0b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/libc-start.c:308:16
    #19 0x407a6d in _start
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/local/bin/../include/c++/v1/__tree:283:54 in

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 nlohmann changed the title UBSAN error while parsing UBJSON UBSAN error while parsing UBJSON (bool) May 12, 2022
@nlohmann
Copy link
Owner Author

FYI @fangq

@nlohmann nlohmann changed the title UBSAN error while parsing UBJSON (bool) UBSAN error while parsing UBJSON (Invalid-bool-value) May 12, 2022
@nlohmann nlohmann changed the title UBSAN error while parsing UBJSON (Invalid-bool-value) UBSAN error while parsing BJData (Invalid-bool-value) May 12, 2022
@nlohmann
Copy link
Owner Author

I analyzed this bug a bit and it seems as if a parse error is not detected and the SAX-DOM parser blows up because of an invalid invariant: it assumes parsing an array, but an unexpected key event comes in which tries to use operator[](const char*) on a std::vector.

I will try to add some assertions there to make this more explicit.

@nlohmann
Copy link
Owner Author

Here are the SAX events triggered by the input:

image

@nlohmann nlohmann added confirmed solution: proposed fix a fix for the issue has been proposed and waits for confirmation 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
1 participant