-
Notifications
You must be signed in to change notification settings - Fork 764
Open
Description
I found a crash in fromJson at json_export.cpp.
Environment
- OS: Ubuntu 22.04
- Compiler: clang 13.0.1
- C++ Standard: C++17
- Sanitizers: AddressSanitizer (ASan) + UndefinedBehaviorSanitizer (UBSan)
Build Instructions
export CXXFLAGS="${CXXFLAGS} -std=c++17 -stdlib=libstdc++ -fsanitize=address -O1 -g"
export CFLAGS="${CFLAGS} -fsanitize=address -O1 -g"
export LDFLAGS="${LDFLAGS} -fsanitize=address"
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DENABLE_FUZZING=ON -DFORCE_STATIC_LINKING=ON -DBUILD_TESTING=OFF
cmake --build . --parallel
Reproduction
Run the fuzzer with a crafted input file:
./bb_fuzzer poc
Observed Behavior
Program crashes with ASan/UBSan report:
/usr/include/c++/11/bits/stl_vector.h:1046:9: runtime error: reference binding to null pointer of type 'nlohmann::basic_json<>'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior .../stl_vector.h:1046:9 in
=================================================================
==352849==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x67e8a1 bp 0x7ffd46a87ad0 sp 0x7ffd46a879c0 T0)
#0 0x67e8a1 in nlohmann::json::is_object() const .../contrib/json.hpp:20661:23
#1 0x67e8a1 in nlohmann::json::operator[](std::string const&) const .../contrib/json.hpp:21446:13
#2 0x666eea in nlohmann::json::operator[]<char const>(char const*) const .../contrib/json.hpp:21467:16
#3 0x663df4 in BT::JsonExporter::fromJson(...) const /root/behavior/behavior_fix/src/json_export.cpp
#4 0x65263c in BT::ImportBlackboardFromJSON(...) /root/behavior/behavior_fix/src/blackboard.cpp:288:39
#5 0x5bea89 in BlackboardFuzzer::fuzzJsonOperations(...) /root/behavior/behavior_fix/fuzzing/bb_fuzzer.cpp:176:7
...
SUMMARY: AddressSanitizer: SEGV .../contrib/json.hpp:20661:23 in nlohmann::json::is_object() const
Root Cause Analysis
JsonExporter::fromJson() assumes the presence of a "__type" field and indexes into JSON objects without first validating their shape. In particular, when source is an array whose first element is not an object, the code does:
BehaviorTree.CPP/src/json_export.cpp
Line 122 in 6731c51
auto type_field = source.is_array() ? source[0]["__type"] : source["__type"]; |
The attached file contains a proof-of-concept.
poc.zip
Metadata
Metadata
Assignees
Labels
No labels