aboutsummaryrefslogtreecommitdiff
path: root/infra
diff options
context:
space:
mode:
authorCatena cyber <35799796+catenacyber@users.noreply.github.com>2021-03-08 16:05:35 +0100
committerGitHub <noreply@github.com>2021-03-08 07:05:35 -0800
commitc41e46ffc8bc409bdfde0c0d2c97e1305f0c4106 (patch)
tree4001fbebec66e846cf957fe69e4b339774132c6f /infra
parent96ae2ed544659c7475a4296d4ee55d4ebd69f37e (diff)
downloadoss-fuzz-c41e46ffc8bc409bdfde0c0d2c97e1305f0c4106.tar.gz
Rust coverage report (for Suricata) (#4697)
* Rust coverage test * Workaround to get rust coverage for Suricata
Diffstat (limited to 'infra')
-rw-r--r--infra/base-images/base-builder/Dockerfile4
-rwxr-xr-xinfra/base-images/base-builder/cargo51
-rwxr-xr-xinfra/base-images/base-builder/compile7
-rwxr-xr-xinfra/base-images/base-clang/checkout_build_install_llvm.sh3
-rwxr-xr-xinfra/base-images/base-runner/Dockerfile9
-rwxr-xr-xinfra/base-images/base-runner/coverage2
-rwxr-xr-xinfra/base-images/base-runner/rcfilt21
-rw-r--r--infra/build/functions/build_and_run_coverage.py2
-rwxr-xr-xinfra/ci/build.py2
-rwxr-xr-xinfra/helper.py2
10 files changed, 96 insertions, 7 deletions
diff --git a/infra/base-images/base-builder/Dockerfile b/infra/base-images/base-builder/Dockerfile
index acfea7a1b..40fdcfbb5 100644
--- a/infra/base-images/base-builder/Dockerfile
+++ b/infra/base-images/base-builder/Dockerfile
@@ -90,6 +90,8 @@ RUN curl https://sh.rustup.rs | sh -s -- -y --default-toolchain=nightly --profil
RUN cargo install cargo-fuzz
# Needed to recompile rust std library for MSAN
RUN rustup component add rust-src --toolchain nightly
+# Set up custom environment variable for source code copy for coverage reports
+ENV OSSFUZZ_RUSTPATH /rust
# Install Bazel through Bazelisk, which automatically fetches the latest Bazel version.
ENV BAZELISK_VERSION 1.7.4
@@ -185,7 +187,7 @@ RUN cd $SRC && \
tar -xzv --strip-components=1 -f $SRC/oss-fuzz.tar.gz && \
rm -rf examples $SRC/oss-fuzz.tar.gz
-COPY compile compile_afl compile_dataflow compile_libfuzzer compile_honggfuzz \
+COPY cargo compile compile_afl compile_dataflow compile_libfuzzer compile_honggfuzz \
compile_go_fuzzer precompile_honggfuzz precompile_afl debug_afl srcmap \
write_labels.py /usr/local/bin/
diff --git a/infra/base-images/base-builder/cargo b/infra/base-images/base-builder/cargo
new file mode 100755
index 000000000..57daea49f
--- /dev/null
+++ b/infra/base-images/base-builder/cargo
@@ -0,0 +1,51 @@
+#!/bin/bash -eu
+# Copyright 2020 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.
+#
+# This is a wrapper around calling cargo
+# This just expands RUSTFLAGS in case of a coverage build
+# We need this until https://github.com/rust-lang/cargo/issues/5450 is merged
+# because cargo uses relative paths for the current crate
+# and absolute paths for its dependencies
+#
+################################################################################
+
+export PATH="/rust/bin:$PATH"
+
+if [ "$SANITIZER" = "coverage" ] && [ $1 = "build" ]
+then
+ crate_src_abspath=`cargo metadata --no-deps --format-version 1 | jq -r '.workspace_root'`
+ export RUSTFLAGS="$RUSTFLAGS --remap-path-prefix src=$crate_src_abspath/src"
+fi
+
+if [ "$SANITIZER" = "coverage" ] && [ $1 = "fuzz" ]
+then
+ fuzz_src_abspath=`pwd`
+ export RUSTFLAGS="$RUSTFLAGS --remap-path-prefix fuzz_targets=$fuzz_src_abspath/fuzz_targets"
+ # hack to turn cargo fuzz build into cargo build so as to get coverage
+ # cargo fuzz adds "--target" "x86_64-unknown-linux-gnu"
+ (
+ # go into fuzz directory if not already the case
+ cd fuzz || true
+ # do not optimize with --release, leading to Malformed instrumentation profile data
+ cargo build --bins
+ # copies the build output in the expected target directory
+ cd target
+ mkdir -p x86_64-unknown-linux-gnu/release
+ cp -r debug/* x86_64-unknown-linux-gnu/release/
+ )
+ exit 0
+fi
+
+cargo "$@"
diff --git a/infra/base-images/base-builder/compile b/infra/base-images/base-builder/compile
index 13f0c5c10..78453c98c 100755
--- a/infra/base-images/base-builder/compile
+++ b/infra/base-images/base-builder/compile
@@ -103,6 +103,11 @@ if [ "$SANITIZER" != "undefined" ] && [ "$SANITIZER" != "coverage" ] && [ "$ARCH
else
export RUSTFLAGS="--cfg fuzzing -Cdebuginfo=1 -Cforce-frame-pointers"
fi
+if [ "$SANITIZER" = "coverage" ]
+then
+ # link to C++ from comment in f5098035eb1a14aa966c8651d88ea3d64323823d
+ export RUSTFLAGS="$RUSTFLAGS -Zinstrument-coverage -C link-arg=-lc++"
+fi
# Add Rust libfuzzer flags.
# See https://github.com/rust-fuzz/libfuzzer/blob/master/build.rs#L12.
@@ -145,7 +150,7 @@ BUILD_CMD="bash -eux $SRC/build.sh"
# We need to preserve source code files for generating a code coverage report.
# We need exact files that were compiled, so copy both $SRC and $WORK dirs.
-COPY_SOURCES_CMD="cp -rL --parents $SRC $WORK /usr/include /usr/local/include $GOPATH $OUT"
+COPY_SOURCES_CMD="cp -rL --parents $SRC $WORK /usr/include /usr/local/include $GOPATH $OSSFUZZ_RUSTPATH $OUT"
if [ "${BUILD_UID-0}" -ne "0" ]; then
adduser -u $BUILD_UID --disabled-password --gecos '' builder
diff --git a/infra/base-images/base-clang/checkout_build_install_llvm.sh b/infra/base-images/base-clang/checkout_build_install_llvm.sh
index 6d9fee7bf..60429106b 100755
--- a/infra/base-images/base-clang/checkout_build_install_llvm.sh
+++ b/infra/base-images/base-clang/checkout_build_install_llvm.sh
@@ -20,7 +20,8 @@
# 2).
NPROC=$(expr $(nproc) / 2)
-LLVM_DEP_PACKAGES="build-essential make cmake ninja-build git python3 g++-multilib binutils-dev"
+# zlib1g-dev is needed for llvm-profdata to handle coverage data from rust compiler
+LLVM_DEP_PACKAGES="build-essential make cmake ninja-build git python3 g++-multilib binutils-dev zlib1g-dev"
apt-get install -y $LLVM_DEP_PACKAGES --no-install-recommends
# Checkout
diff --git a/infra/base-images/base-runner/Dockerfile b/infra/base-images/base-runner/Dockerfile
index 3237916d4..ee44768cd 100755
--- a/infra/base-images/base-runner/Dockerfile
+++ b/infra/base-images/base-runner/Dockerfile
@@ -68,6 +68,7 @@ RUN apt-get update && apt-get install -y \
python3 \
python3-pip \
wget \
+ curl \
zip
RUN git clone https://chromium.googlesource.com/chromium/src/tools/code_coverage /opt/code_coverage && \
@@ -83,6 +84,13 @@ ENV UBSAN_OPTIONS="print_stacktrace=1:print_summary=1:silence_unsigned_overflow=
ENV FUZZER_ARGS="-rss_limit_mb=2560 -timeout=25"
ENV AFL_FUZZER_ARGS="-m none"
+# Install rustfilt for symbol demangling.
+ENV CARGO_HOME=/rust
+ENV RUSTUP_HOME=/rust/rustup
+ENV PATH=$PATH:/rust/bin
+RUN curl https://sh.rustup.rs | sh -s -- -y --default-toolchain=nightly
+RUN cargo install rustfilt
+
# Install OpenJDK 15 and trim its size by removing unused components.
ENV JAVA_HOME=/usr/lib/jvm/java-15-openjdk-amd64
ENV JVM_LD_LIBRARY_PATH=$JAVA_HOME/lib/server
@@ -103,6 +111,7 @@ COPY bad_build_check \
dataflow_tracer.py \
download_corpus \
minijail0 \
+ rcfilt \
reproduce \
run_fuzzer \
run_minijail \
diff --git a/infra/base-images/base-runner/coverage b/infra/base-images/base-runner/coverage
index 2fcf9e977..76e77ec2b 100755
--- a/infra/base-images/base-runner/coverage
+++ b/infra/base-images/base-runner/coverage
@@ -193,7 +193,7 @@ else
# Generate HTML report.
llvm-cov show -format=html -output-dir=$REPORT_ROOT_DIR \
- -Xdemangler c++filt -Xdemangler -n $LLVM_COV_ARGS
+ -Xdemangler rcfilt $LLVM_COV_ARGS
# Export coverage summary in JSON format.
llvm-cov export -summary-only $LLVM_COV_ARGS > $SUMMARY_FILE
diff --git a/infra/base-images/base-runner/rcfilt b/infra/base-images/base-runner/rcfilt
new file mode 100755
index 000000000..1c621100c
--- /dev/null
+++ b/infra/base-images/base-runner/rcfilt
@@ -0,0 +1,21 @@
+#!/bin/bash -u
+# Copyright 2020 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.
+#
+# Symbol demangling for both C++ and Rust
+#
+################################################################################
+
+# simply pipe
+rustfilt | c++filt -n
diff --git a/infra/build/functions/build_and_run_coverage.py b/infra/build/functions/build_and_run_coverage.py
index 71d7338f9..cc2de5a32 100644
--- a/infra/build/functions/build_and_run_coverage.py
+++ b/infra/build/functions/build_and_run_coverage.py
@@ -48,7 +48,7 @@ LATEST_REPORT_INFO_CONTENT_TYPE = 'application/json'
UPLOAD_URL_FORMAT = 'gs://' + COVERAGE_BUCKET_NAME + '/{project}/{type}/{date}'
# Languages from project.yaml that have code coverage support.
-LANGUAGES_WITH_COVERAGE_SUPPORT = ['c', 'c++', 'go']
+LANGUAGES_WITH_COVERAGE_SUPPORT = ['c', 'c++', 'go', 'rust']
def usage():
diff --git a/infra/ci/build.py b/infra/ci/build.py
index f71799bb2..addeb7879 100755
--- a/infra/ci/build.py
+++ b/infra/ci/build.py
@@ -32,7 +32,7 @@ DEFAULT_ENGINES = ['afl', 'honggfuzz', 'libfuzzer']
DEFAULT_SANITIZERS = ['address', 'undefined']
# Languages from project.yaml that have code coverage support.
-LANGUAGES_WITH_COVERAGE_SUPPORT = ['c', 'c++', 'go']
+LANGUAGES_WITH_COVERAGE_SUPPORT = ['c', 'c++', 'go', 'rust']
def get_changed_files_output():
diff --git a/infra/helper.py b/infra/helper.py
index 47b42e668..6048d9771 100755
--- a/infra/helper.py
+++ b/infra/helper.py
@@ -59,7 +59,7 @@ CORPUS_BACKUP_URL_FORMAT = (
PROJECT_LANGUAGE_REGEX = re.compile(r'\s*language\s*:\s*([^\s]+)')
# Languages from project.yaml that have code coverage support.
-LANGUAGES_WITH_COVERAGE_SUPPORT = ['c', 'c++', 'go']
+LANGUAGES_WITH_COVERAGE_SUPPORT = ['c', 'c++', 'go', 'rust']
# pylint: disable=too-many-lines