From 09c0f98ebcbf4b377c5e19b14786fba4c5a00dd5 Mon Sep 17 00:00:00 2001 From: Bhargava Shastry Date: Fri, 20 Dec 2019 22:41:52 +0100 Subject: [PATCH] [boost] Assert post conditions for match (#3018) * boost: Assert post conditions for match * boost: Fix broken build * boost regex: Use fuzzeddataprovider to extract regex pattern and text --- projects/boost/Dockerfile | 3 -- projects/boost/boost_regex_fuzzer.cc | 49 +++++++++++++++++++++++----- projects/boost/build.sh | 3 +- projects/boost/project.yaml | 1 + 4 files changed, 43 insertions(+), 13 deletions(-) diff --git a/projects/boost/Dockerfile b/projects/boost/Dockerfile index 6134c2227..ac2fe3768 100644 --- a/projects/boost/Dockerfile +++ b/projects/boost/Dockerfile @@ -19,8 +19,5 @@ RUN apt-get update && apt-get install -y g++ RUN git clone --recursive https://github.com/boostorg/boost.git WORKDIR boost -# This bootstrap boost with the g++ toolchain. -# The actual build will need to use CXX/CXXFLAGS provided by OSS-Fuzz. -RUN ./bootstrap.sh && ./b2 headers # Preferably, move boost_regex_fuzzer.cc to the boost repository. COPY build.sh *.cc $SRC/ diff --git a/projects/boost/boost_regex_fuzzer.cc b/projects/boost/boost_regex_fuzzer.cc index c2383791b..018a04b4b 100644 --- a/projects/boost/boost_regex_fuzzer.cc +++ b/projects/boost/boost_regex_fuzzer.cc @@ -1,16 +1,47 @@ // From https://svn.boost.org/trac10/ticket/12818 // This fuzz target can likely be enhanced to exercise more code. // The ideal place for this fuzz target is the boost repository. -#include -extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { - try { - std::string str((char *)Data, Size); - boost::regex e(str); - boost::match_results what; - boost::regex_match(str, what, e, - boost::match_default | boost::match_partial); +#ifdef DEBUG +#include +#endif - } catch (const std::exception &) { +#include +#include + +namespace { + void assertPostConditions(boost::match_results const& match, boost::regex const& e) + { + // See https://www.boost.org/doc/libs/1_71_0/libs/regex/doc/html/boost_regex/ref/regex_match.html + assert(match.size() == e.mark_count() + 1); + assert(!match.empty()); + assert(!match.prefix().matched); + assert(!match.suffix().matched); + } +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + FuzzedDataProvider fuzzed_data(Data, Size); + // First value is length of the regex string + size_t regex_length = fuzzed_data.ConsumeIntegral(); + // Second value is regexp string whose length is `regex_length` + std::string regex_string = fuzzed_data.ConsumeBytesAsString(regex_length); + boost::regex e(regex_string); + // Last value is the text to be matched + std::string text = fuzzed_data.ConsumeRemainingBytesAsString(); + +#ifdef DEBUG + std::cout << "Regexp string: " << regex_string << "Size: " << regex_string.size() << std::endl; + std::cout << "Text: " << text << "Size: " << text.size() << std::endl; +#endif + + try { + boost::match_results what; + bool match = boost::regex_match(text, what, e, + boost::match_default | boost::match_partial); + if (match) + assertPostConditions(what, e); + } + catch (const std::runtime_error &) { } return 0; } diff --git a/projects/boost/build.sh b/projects/boost/build.sh index abd7a3c9d..b34d55f35 100755 --- a/projects/boost/build.sh +++ b/projects/boost/build.sh @@ -15,9 +15,10 @@ # ################################################################################ +# Build boost +./bootstrap.sh && ./b2 headers # Very simple build rule, but sufficient here. - #boost regexp $CXX $CXXFLAGS -I . ../boost_regex_fuzzer.cc libs/regex/src/*.cpp $LIB_FUZZING_ENGINE -o boost_regex_fuzzer diff --git a/projects/boost/project.yaml b/projects/boost/project.yaml index 7ea1b586d..e46f5a439 100644 --- a/projects/boost/project.yaml +++ b/projects/boost/project.yaml @@ -5,4 +5,5 @@ homepage: "http://www.boost.org/" auto_ccs: - "jz.maddock@googlemail.com" - "mclow@boost.org" + - "bshas3@gmail.com" # - "someone-else@boost.org"