Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Null dereference in JsonExporter::fromJson due to missing __type validation #1008

@ahuo1

Description

@ahuo1

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:

auto type_field = source.is_array() ? source[0]["__type"] : source["__type"];

The attached file contains a proof-of-concept.
poc.zip

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions