Environment
- OS: Ubuntu 22.04
- Compiler: clang 13.0.1
- Sanitizers: AddressSanitizer (ASan) + UndefinedBehaviorSanitizer (UBSan)
Build Instructions
export CC=clang-13
export CXX=clang++-13
export CXXFLAGS="${CXXFLAGS} -std=c++17 -stdlib=libstdc++ -fsanitize=address -O1 -g"
export CFLAGS="${CFLAGS} -fsanitize=address -O1 -g"
export LDFLAGS="${LDFLAGS} -fsanitize=address"
export LIB_FUZZING_ENGINE="-fsanitize=fuzzer"
sed -i 's/CMAKE_CXX_STANDARD 11/CMAKE_CXX_STANDARD 17/g' CMakeLists.txt
sed -i 's/std::random/\/\/std::random/g' test/*.cpp
mkdir build && cd build
cmake .. -DBUILD_SHARED=OFF -DBUILD_MIXED=ON
make -j $(nproc)
Reproduction
Run the fuzzer with a crafted input file:
Observed Behavior
Program crashes with ASan/UBSan report:
==1084272==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000014108 at pc 0x00000087512e bp 0x7ffc45ef9ba0 sp 0x7ffc45ef9b98
READ of size 8 at 0x603000014108 thread T0
...
#1 0x864a45 in std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::shared_ptr<OpenBabel::OBMol>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::shared_ptr<OpenBabel::OBMol> > > >::find(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_map.h:1170:21
#2 0x864a45 in OpenBabel::ChemKinFormat::CheckSpecies(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, bool) /root/openbabel/src/formats/chemkinformat.cpp:653:35
#3 0x85f01a in OpenBabel::ChemKinFormat::ReadReactionQualifierLines(std::istream&, OpenBabel::OBReaction*) /root/openbabel/src/formats/chemkinformat.cpp:633:34
#4 0x852319 in OpenBabel::ChemKinFormat::ReadMolecule(OpenBabel::OBBase*, OpenBabel::OBConversion*) /root/openbabel/src/formats/chemkinformat.cpp:207:8
#5 0x86e92b in OpenBabel::ChemKinFormat::ReadChemObject(OpenBabel::OBConversion*) /root/openbabel/src/formats/chemkinformat.cpp:123:14
#6 0x5b247b in OpenBabel::OBConversion::Convert() /root/openbabel/src/obconversion.cpp:542:30
#7 0x5b140c in OpenBabel::OBConversion::Convert(std::istream*, std::ostream*) /root/openbabel/src/obconversion.cpp:478:17
...
Root Cause Analysis
The crash happens in OpenBabel::ChemKinFormat::CheckSpecies when calling std::map::find. A malformed or unchecked string from input is used as the lookup key, which becomes corrupted. This leads to an out-of-bounds read inside the map’s internal data structure.
The attached file contains a proof-of-concept.
poc.zip
Environment
Build Instructions
Reproduction
Run the fuzzer with a crafted input file:
Observed Behavior
Program crashes with ASan/UBSan report:
Root Cause Analysis
The crash happens in OpenBabel::ChemKinFormat::CheckSpecies when calling std::map::find. A malformed or unchecked string from input is used as the lookup key, which becomes corrupted. This leads to an out-of-bounds read inside the map’s internal data structure.
The attached file contains a proof-of-concept.
poc.zip