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:
==1072920==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000030 (pc 0x00000083677a bp 0x7ffc68ded350 sp 0x7ffc68decfe0 T0)
==1072920==The signal is caused by a READ memory access.
==1072920==Hint: address points to the zero page.
#0 0x83677a in OpenBabel::OBAtom::GetIdx() const /root/openbabel/include/openbabel/atom.h:245:59
#1 0x83677a in OpenBabel::CacaoFormat::SetHilderbrandt(OpenBabel::OBMol&, std::vector<OpenBabel::OBInternalCoord*, std::allocator<OpenBabel::OBInternalCoord*> >&) /root/openbabel/src/formats/cacaoformat.cpp:254:36
#2 0x837512 in OpenBabel::CacaoInternalFormat::WriteMolecule(OpenBabel::OBBase*, OpenBabel::OBConversion*) /root/openbabel/src/formats/cacaoformat.cpp:343:5
#3 0xea3d0f in OpenBabel::OBMoleculeFormat::WriteChemObjectImpl(OpenBabel::OBConversion*, OpenBabel::OBFormat*) /root/openbabel/src/obmolecformat.cpp:173:26
#4 0x5b28d1 in OpenBabel::OBConversion::Convert() /root/openbabel/src/obconversion.cpp:604:40
#5 0x5b140c in OpenBabel::OBConversion::Convert(std::istream*, std::ostream*) /root/openbabel/src/obconversion.cpp:478:17
#6 0x5a5c18 in LLVMFuzzerTestOneInput /root/openbabel/test/fuzz/fuzz_convert.cpp:35:14
#7 0x4d93b3 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/root/openbabel/build/bin/fuzz_convert+0x4d93b3)
...
Root Cause Analysis
The crash occurs because SetHilderbrandt assumes that all OBAtom* pointers in its internal coordinate list are valid. In this case, a null or corrupted pointer is passed, leading to a dereference at address 0x30.
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 occurs because SetHilderbrandt assumes that all OBAtom* pointers in its internal coordinate list are valid. In this case, a null or corrupted pointer is passed, leading to a dereference at address 0x30.
The attached file contains a proof-of-concept.
poc.zip