From 9fed4d58cb0a5ced24813527d4d94a17bc7ef5cd Mon Sep 17 00:00:00 2001 From: "Jip J. Dekker" Date: Tue, 6 Aug 2019 04:16:09 +1000 Subject: [PATCH] [minizinc] Initial Fuzzer (#2656) --- projects/minizinc/Dockerfile | 24 +++++++++++ projects/minizinc/build.sh | 32 +++++++++++++++ projects/minizinc/minizinc_fuzzer.cpp | 48 ++++++++++++++++++++++ projects/minizinc/minizinc_fuzzer.dict | 50 +++++++++++++++++++++++ projects/minizinc/minizinc_fuzzer.options | 3 ++ projects/minizinc/project.yaml | 1 - 6 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 projects/minizinc/Dockerfile create mode 100755 projects/minizinc/build.sh create mode 100644 projects/minizinc/minizinc_fuzzer.cpp create mode 100644 projects/minizinc/minizinc_fuzzer.dict create mode 100644 projects/minizinc/minizinc_fuzzer.options diff --git a/projects/minizinc/Dockerfile b/projects/minizinc/Dockerfile new file mode 100644 index 000000000..70a58ea12 --- /dev/null +++ b/projects/minizinc/Dockerfile @@ -0,0 +1,24 @@ +# Copyright 2019 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +################################################################################ + +FROM gcr.io/oss-fuzz-base/base-builder +MAINTAINER Harsil S. Patel +RUN apt-get update && apt-get install -y make autoconf automake libtool cmake git build-essential curl +RUN curl -L https://gitlab.com/minizinc/minizinc-afl-seed-corpus/-/archive/master/minizinc-afl-seed-corpus-master.zip -o $SRC/minizinc_fuzzer_seed_corpus.zip +RUN git clone --depth 1 --branch develop https://github.com/MiniZinc/libminizinc.git minizinc +COPY minizinc_fuzzer.cpp minizinc/ +WORKDIR minizinc +COPY build.sh minizinc_fuzzer.dict minizinc_fuzzer.options $SRC/ \ No newline at end of file diff --git a/projects/minizinc/build.sh b/projects/minizinc/build.sh new file mode 100755 index 000000000..9cd1c0889 --- /dev/null +++ b/projects/minizinc/build.sh @@ -0,0 +1,32 @@ +#!/bin/bash -eu +# Copyright 2019 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +################################################################################ + +build_dir=$WORK/build + +mkdir -p $build_dir +pushd $build_dir +cmake $SRC/minizinc -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=$WORK/install +cmake --build . --target install -- -j$(nproc) +popd + +$CXX $CXXFLAGS -std=c++11 -I$WORK/install/include $SRC/minizinc/minizinc_fuzzer.cpp -o $OUT/minizinc_fuzzer $LIB_FUZZING_ENGINE $WORK/install/lib/libmzn.a + +rm -rf $OUT/share +mv $WORK/install/share $OUT +mv $SRC/minizinc_fuzzer_seed_corpus.zip $OUT/minizinc_fuzzer_seed_corpus.zip +mv $SRC/minizinc_fuzzer.dict $OUT/minizinc_fuzzer.dict +mv $SRC/minizinc_fuzzer.options $OUT/minizinc_fuzzer.options \ No newline at end of file diff --git a/projects/minizinc/minizinc_fuzzer.cpp b/projects/minizinc/minizinc_fuzzer.cpp new file mode 100644 index 000000000..c3b612925 --- /dev/null +++ b/projects/minizinc/minizinc_fuzzer.cpp @@ -0,0 +1,48 @@ +#include + +using namespace std; +using namespace MiniZinc; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + + Timer starttime; + bool fSuccess = false; + try { + MznSolver slv(std::cout,std::cerr); + try { + std::string model = std::string(reinterpret_cast(Data), Size); + std::vector args({"-c","--solver","org.minizinc.mzn-fzn"}); + fSuccess = (slv.run(args, model, "minizinc", "model.mzn") != SolverInstance::ERROR); + } catch (const LocationException& e) { + if (slv.get_flag_verbose()) + std::cerr << std::endl; + std::cerr << e.loc() << ":" << std::endl; + std::cerr << e.what() << ": " << e.msg() << std::endl; + } catch (const Exception& e) { + if (slv.get_flag_verbose()) + std::cerr << std::endl; + std::string what = e.what(); + std::cerr << what << (what.empty() ? "" : ": ") << e.msg() << std::endl; + } + catch (const exception& e) { + if (slv.get_flag_verbose()) + std::cerr << std::endl; + std::cerr << e.what() << std::endl; + } + catch (...) { + if (slv.get_flag_verbose()) + std::cerr << std::endl; + std::cerr << " UNKNOWN EXCEPTION." << std::endl; + } + + if (slv.get_flag_verbose()) { + std::cerr << " Done ("; + cerr << "overall time " << starttime.stoptime() << ")." << std::endl; + } + } catch (const Exception& e) { + std::string what = e.what(); + std::cerr << what << (what.empty() ? "" : ": ") << e.msg() << std::endl; + } + + return 0; // Non-zero return values are reserved for future use. +} diff --git a/projects/minizinc/minizinc_fuzzer.dict b/projects/minizinc/minizinc_fuzzer.dict new file mode 100644 index 000000000..79db04dca --- /dev/null +++ b/projects/minizinc/minizinc_fuzzer.dict @@ -0,0 +1,50 @@ +reserved_keyword_0="ann" +reserved_keyword_1="annotation" +reserved_keyword_2="any" +reserved_keyword_3="array" +reserved_keyword_4="bool" +reserved_keyword_5="case" +reserved_keyword_6="constraint" +reserved_keyword_7="diff" +reserved_keyword_8="div" +reserved_keyword_9="else" +reserved_keyword_10="elseif" +reserved_keyword_11="endif" +reserved_keyword_12="enum" +reserved_keyword_13="false" +reserved_keyword_14="float" +reserved_keyword_15="function" +reserved_keyword_16="if" +reserved_keyword_17="in" +reserved_keyword_18="include" +reserved_keyword_19="int" +reserved_keyword_20="intersect" +reserved_keyword_21="let" +reserved_keyword_22="list" +reserved_keyword_23="maximize" +reserved_keyword_24="minimize" +reserved_keyword_25="mod" +reserved_keyword_26="not" +reserved_keyword_27="of" +reserved_keyword_28="op" +reserved_keyword_29="opt" +reserved_keyword_30="output" +reserved_keyword_31="par" +reserved_keyword_32="predicate" +reserved_keyword_33="record" +reserved_keyword_34="satisfy" +reserved_keyword_35="set" +reserved_keyword_36="solve" +reserved_keyword_37="string" +reserved_keyword_38="subset" +reserved_keyword_39="superset" +reserved_keyword_40="symdiff" +reserved_keyword_41="test" +reserved_keyword_42="then" +reserved_keyword_43="true" +reserved_keyword_44="tuple" +reserved_keyword_45="type" +reserved_keyword_46="union" +reserved_keyword_47="var" +reserved_keyword_48="where" +reserved_keyword_49="xor" \ No newline at end of file diff --git a/projects/minizinc/minizinc_fuzzer.options b/projects/minizinc/minizinc_fuzzer.options new file mode 100644 index 000000000..6819d2e9b --- /dev/null +++ b/projects/minizinc/minizinc_fuzzer.options @@ -0,0 +1,3 @@ +[libfuzzer] +only_ascii = 1 +detect_leaks = 0 \ No newline at end of file diff --git a/projects/minizinc/project.yaml b/projects/minizinc/project.yaml index a1539cfe5..670cb5a40 100644 --- a/projects/minizinc/project.yaml +++ b/projects/minizinc/project.yaml @@ -7,4 +7,3 @@ sanitizers: - address - memory: experimental: True - - undefined