diff --git a/projects/eigen/Dockerfile b/projects/eigen/Dockerfile new file mode 100644 index 000000000..4d442dd04 --- /dev/null +++ b/projects/eigen/Dockerfile @@ -0,0 +1,22 @@ +# 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 eigen-core-team@lists.tuxfamily.org +RUN apt-get update && apt-get install --yes cmake mercurial +RUN hg clone https://GOOGLE-AUTOFUZZ@bitbucket.org/eigen/eigen +WORKDIR eigen +COPY build.sh solver_fuzzer.cc $SRC/ diff --git a/projects/eigen/build.sh b/projects/eigen/build.sh new file mode 100755 index 000000000..0c90a1751 --- /dev/null +++ b/projects/eigen/build.sh @@ -0,0 +1,29 @@ +#!/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 project +mkdir build_dir && cd build_dir +cmake .. +make install +cd .. + +# build fuzzers +for fuzzers in $(find $SRC -name '*_fuzzer.cc'); do + fuzz_basename=$(basename -s .cc $fuzzers) + $CXX $CXXFLAGS -std=c++11 -I. -Isrc/Eigen/Core \ + $fuzzers -o $OUT/$fuzz_basename $LIB_FUZZING_ENGINE +done diff --git a/projects/eigen/project.yaml b/projects/eigen/project.yaml new file mode 100644 index 000000000..1968313d0 --- /dev/null +++ b/projects/eigen/project.yaml @@ -0,0 +1,6 @@ +homepage: "http://eigen.tuxfamily.org/index.php?title=Main_Page" +primary_contact: "eigen-core-team@lists.tuxfamily.org" +sanitizers: + - address + - memory + - undefined diff --git a/projects/eigen/solver_fuzzer.cc b/projects/eigen/solver_fuzzer.cc new file mode 100644 index 000000000..86651ecf0 --- /dev/null +++ b/projects/eigen/solver_fuzzer.cc @@ -0,0 +1,71 @@ +// Copyright 2019 Google LLC +// +// 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. + +#include +#include +#include +#include + +#include "Eigen/Core" +#include "Eigen/src/Core/Matrix.h" + +using ::Eigen::Matrix; +using ::Eigen::Dynamic; +using ::Eigen::Lower; +using ::Eigen::Upper; + +int ConsumeNextInt(const uint8_t** data, size_t* size) { + if (*size < sizeof(int)) { + return 0; + } + int result; + memcpy(&result, *data, sizeof(int)); + *size -= sizeof(int); + *data += sizeof(int); + return result; +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + const size_t rows = static_cast(ConsumeNextInt(&data, &size)); + const size_t columns = static_cast(ConsumeNextInt(&data, &size)); + + if (rows == 0 || columns == 0) { + return 0; + } + if (rows > 1024 || columns > 1024) { + return 0; + } + + // We can do this same fuzz test with other templated types. Here, we just use + // an int. + Matrix vec(rows); + for (size_t i = 0; i < rows; ++i) { + vec(i) = ConsumeNextInt(&data, &size); + } + Matrix matrix(rows, columns); + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < columns; ++j) { + matrix(i, j) = ConsumeNextInt(&data, &size); + } + } + + matrix.template triangularView().solve(vec); + matrix.template triangularView().solve(vec); + matrix.conjugate().template triangularView().solve(vec); + matrix.conjugate().template triangularView().solve(vec); + matrix.transpose().template triangularView().solve(vec); + matrix.transpose().template triangularView().solve(vec); + + return 0; +}