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

Skip to content

Crash in XMLParser::PImpl::loadDocImpl when <include> tag is missing path attribute #1003

@ahuo1

Description

@ahuo1

Hi, I found a null pointer vulnerability using my fuzzer.

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:

./bt_fuzzer poc

Observed Behavior

Program crashes with ASan/UBSan report:

==26672==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f0714d680bc bp 0x7ffc9e93ced0 sp 0x7ffc9e93c688 T0)
==26672==The signal is caused by a READ memory access.
==26672==Hint: address points to the zero page.
    ...
    #5 0x8261dd in std::filesystem::__cxx11::path::path<char const*, std::filesystem::__cxx11::path>(char const* const&, std::filesystem::__cxx11::path::format) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/fs_path.h:289:32
    #6 0x82173f in BT::XMLParser::PImpl::loadDocImpl(tinyxml2::XMLDocument*, bool) /root/behavior/behaviortreecpp/src/xml_parsing.cpp:265:20
    #7 0x82398b in BT::XMLParser::loadFromText(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool) /root/behavior/behaviortreecpp/src/xml_parsing.cpp:174:7
    #8 0x5d6a2f in BT::BehaviorTreeFactory::createTreeFromText(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<BT::Blackboard>) /root/behavior/behaviortreecpp/src/bt_factory.cpp:347:10
    #9 0x5c2263 in LLVMFuzzerTestOneInput /root/behavior/behaviortreecpp/fuzzing/bt_fuzzer.cpp:79:17
    #10 0x44c583 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/root/behavior/behaviortreecpp/build/bt_fuzzer+0x44c583)
    #11 0x4353cf in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) (/root/behavior/behaviortreecpp/build/bt_fuzzer+0x4353cf)
    ...

Root Cause Analysis

In xml_parsing.cpp the following code is used:

#if __bt_cplusplus >= 202002L
auto file_path(std::filesystem::path(incl_node->Attribute("path")));
#else
auto file_path(std::filesystem::u8path(incl_node->Attribute("path")));
#endif
const char* ros_pkg_relative_path = incl_node->Attribute("ros_pkg");

Here, incl_node->Attribute("path") may return nullptr if the tag in the XML does not provide a path attribute. This nullptr is then passed directly into std::filesystem::path, which expects a valid non-null C string. Passing nullptr invokes undefined behavior, causing the runtime crash.

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