Skip to content

Bug Report: Overlapping memcpy in zlib_stream::basic_unzip_streambuf::underflow #2832

Description

@ahuo1

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:

./fuzz_convert poc

Observed Behavior

Program crashes with ASan/UBSan report:

==1090813==ERROR: AddressSanitizer: memcpy-param-overlap: memory ranges [0x621000002900,0x621000002904) and [0x621000002903, 0x621000002907) overlap
    #0 0x5700d4 in __asan_memcpy (/root/openbabel/build/bin/fuzz_convert+0x5700d4)
    #1 0x5ca7a9 in zlib_stream::basic_unzip_streambuf<char, std::char_traits<char> >::underflow() /root/openbabel/src/zipstreamimpl.h:361:5
    #2 0x7f9ef34118e5 in std::basic_streambuf<char, std::char_traits<char> >::uflow() (/lib/x86_64-linux-gnu/libstdc++.so.6+0x14a8e5)
    #3 0x7f9ef33e7f4d in std::istream::get() (/lib/x86_64-linux-gnu/libstdc++.so.6+0x120f4d)
    #4 0x5cbaf3 in OpenBabel::LineEndingExtractor::operator()(std::istream&) /root/openbabel/include/openbabel/lineend.h:174:17
    #5 0x5cbaf3 in OpenBabel::FilteringInputStreambuf<OpenBabel::LineEndingExtractor>::underflow() /root/openbabel/include/openbabel/lineend.h:136:16
    #6 0x7f9ef338e1c9 in std::istream::getline(char*, long, char) (/lib/x86_64-linux-gnu/libstdc++.so.6+0xc71c9)
    #7 0x8c4547 in std::istream::getline(char*, long) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/istream:428:22
    #8 0x8c4547 in OpenBabel::DlpolyInputReader::ParseHeader(std::istream&, OpenBabel::OBMol&) /root/openbabel/src/formats/dlpolyformat.cpp:106:16
    #9 0x8cbc6d in OpenBabel::DlpolyConfigFormat::ReadMolecule(OpenBabel::OBBase*, OpenBabel::OBConversion*) /root/openbabel/src/formats/dlpolyformat.cpp:310:12
...

Root Cause Analysis

The crash occurs because memcpy is used to copy overlapping memory regions in basic_unzip_streambuf::underflow(). Since memcpy is not defined for overlapping ranges, this leads to undefined behavior and triggers the memcpy-param-overlap error.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions