Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[fuzz] add fuzz coverage CI check #11045

Merged
merged 52 commits into from
Jul 19, 2020
Merged
Show file tree
Hide file tree
Changes from 49 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
6cf628a
add fuzz coverage CI check
asraa May 4, 2020
b1e585f
add workflow
asraa May 4, 2020
1c4a2db
Merge remote-tracking branch 'upstream/master' into add-fuzz-ci
asraa May 5, 2020
c30d149
JUST FOR CI FAILURE
asraa May 8, 2020
89b95da
just make this mergeable with gtest
asraa May 8, 2020
ef0701c
Merge remote-tracking branch 'upstream/master' into add-fuzz-ci
asraa May 20, 2020
f9266bb
fix dependency
asraa May 21, 2020
9e4b175
fix coverage publish
asraa May 21, 2020
da63fbb
Merge remote-tracking branch 'upstream/master' into add-fuzz-ci
asraa May 21, 2020
2ce6603
fix
asraa May 21, 2020
baa334f
fixup
asraa May 21, 2020
90f49ab
hopefully all fixed
asraa May 21, 2020
d8e804e
Merge remote-tracking branch 'upstream/master' into add-fuzz-ci
asraa May 26, 2020
b0588cc
Merge remote-tracking branch 'upstream/master' into add-fuzz-ci
asraa May 28, 2020
b1b3f54
add azp job
asraa May 28, 2020
874b806
naming
asraa May 28, 2020
056c439
Merge remote-tracking branch 'upstream/master' into add-fuzz-ci
asraa May 28, 2020
0c61268
fix newline
asraa May 28, 2020
0a9b839
use matrix
asraa May 29, 2020
4b8548a
fix
asraa May 29, 2020
37130ee
Merge remote-tracking branch 'upstream/master' into add-fuzz-ci
asraa May 29, 2020
afbcd2b
Merge remote-tracking branch 'upstream/master' into add-fuzz-ci
asraa Jun 1, 2020
2c21084
address comments
asraa Jun 1, 2020
0bd3e81
fix
asraa Jun 1, 2020
2586e40
pie
asraa Jun 9, 2020
b8ac2a2
fix pie
asraa Jun 10, 2020
48a423f
reduce size of binary and don't fail while fuzzing
asraa Jun 10, 2020
a183518
fix
asraa Jun 10, 2020
463234c
just make binary smaller
asraa Jun 10, 2020
1a0ef25
only instrument coverage over successful corpus
asraa Jun 11, 2020
afa8b13
Merge remote-tracking branch 'upstream/master' into add-fuzz-ci
asraa Jun 15, 2020
2df8337
Merge remote-tracking branch 'upstream/master' into add-fuzz-ci
asraa Jun 18, 2020
c0f293f
dont use asan or libc++
asraa Jun 18, 2020
7cebc32
test what happens with just -fsanitize=fuzzer
asraa Jun 22, 2020
08a0531
Merge remote-tracking branch 'upstream/master' into add-fuzz-ci
asraa Jun 22, 2020
7a6f975
Merge remote-tracking branch 'upstream/master' into add-fuzz-ci
asraa Jun 23, 2020
6b0354c
optimize for binary size
asraa Jun 23, 2020
11850bf
ready for review
asraa Jun 25, 2020
25bac35
max size and leak detect
asraa Jun 25, 2020
ad35385
remove libc++ workaround
asraa Jun 25, 2020
aebe031
Merge remote-tracking branch 'upstream/master' into add-fuzz-ci
asraa Jun 25, 2020
3b2dddd
test bin
asraa Jun 25, 2020
4d3598c
add limits and fix script
asraa Jun 26, 2020
cb9b593
Merge remote-tracking branch 'upstream/master' into add-fuzz-ci
asraa Jul 13, 2020
59ce7c4
fix fuzz filtering
asraa Jul 13, 2020
a33f522
fix script
asraa Jul 13, 2020
d77c18b
no more exception issues
asraa Jul 16, 2020
bbaaf58
Merge remote-tracking branch 'upstream/master' into add-fuzz-ci
asraa Jul 16, 2020
a4e3e2f
fix router fuzz test
asraa Jul 16, 2020
f94c392
address comment
asraa Jul 16, 2020
7ea6e16
fix syntax
asraa Jul 16, 2020
4a212b2
address comments
asraa Jul 17, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions .azure-pipelines/pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,21 +90,28 @@ jobs:
ciTarget: $(CI_TARGET)

- job: coverage
displayName: "Linux-x64 coverage"
displayName: "Linux-x64"
dependsOn: ["format"]
asraa marked this conversation as resolved.
Show resolved Hide resolved
timeoutInMinutes: 360
pool: "x64-large"
strategy:
maxParallel: 2
matrix:
coverage:
CI_TARGET: "coverage"
fuzz_coverage:
CI_TARGET: "fuzz_coverage"
steps:
- template: bazel.yml
parameters:
managedAgent: false
ciTarget: bazel.coverage
ciTarget: bazel.$(CI_TARGET)
rbe: false
# /tmp/sandbox_base is a tmpfs in CI environment to optimize large I/O for coverage traces
bazelBuildExtraOptions: "--test_env=ENVOY_IP_TEST_VERSIONS=v4only --sandbox_base=/tmp/sandbox_base"

- script: ci/run_envoy_docker.sh 'ci/upload_gcs_artifact.sh /source/generated/coverage coverage'
displayName: "Upload Report to GCS"
- script: ci/run_envoy_docker.sh 'ci/upload_gcs_artifact.sh /source/generated/$(CI_TARGET) $(CI_TARGET)'
displayName: "Upload $(CI_TARGET) Report to GCS"
env:
ENVOY_DOCKER_BUILD_DIR: $(Build.StagingDirectory)
GCP_SERVICE_ACCOUNT_KEY: $(GcpServiceAccountKey)
Expand Down
10 changes: 6 additions & 4 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -234,18 +234,20 @@ build:remote-ci --remote_cache=grpcs://remotebuildexecution.googleapis.com
build:remote-ci --remote_executor=grpcs://remotebuildexecution.googleapis.com

# Fuzz builds
build:asan-fuzzer --config=clang-asan
# -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION is passed in in the bazel build target
# rules for fuzz tests. Passing it in the CLI will cause dependencies to be build
# with the macro. Causing issues in RouteMatcherTest.TestRoutes that expect prod
# behavior from RE2 library.
build:asan-fuzzer --config=asan
build:asan-fuzzer --define=FUZZING_ENGINE=libfuzzer
build:asan-fuzzer --copt=-fsanitize=fuzzer-no-link
build:asan-fuzzer --copt=-fno-omit-frame-pointer
build:asan-fuzzer --copt=-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
# Remove UBSAN halt_on_error to avoid crashing on protobuf errors.
build:asan-fuzzer --test_env=UBSAN_OPTIONS=print_stacktrace=1

# Fuzzing without ASAN. This is useful for profiling fuzzers without any ASAN artifacts.
build:plain-fuzzer --define=FUZZING_ENGINE=libfuzzer
build:plain-fuzzer --copt=-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
build:plain-fuzzer --copt=-fsanitize=fuzzer-no-link
build:plain-fuzzer --define ENVOY_CONFIG_ASAN=1

# Compile database generation config
# We don't care about built binaries so always strip and use fastbuild.
Expand Down
8 changes: 7 additions & 1 deletion bazel/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -638,13 +638,19 @@ test/run_envoy_bazel_coverage.sh
The summary results are printed to the standard output and the full coverage
report is available in `generated/coverage/coverage.html`.

To generate coverage results for fuzz targets, use the `FUZZ_COVERAGE` environment variable, e.g.:
```
FUZZ_COVERAGE=true VALIDATE_COVERAGE=false test/run_envoy_bazel_coverage.sh
```
This generates a coverage report for fuzz targets after running the target for one minute against fuzzing engine libfuzzer using its coprus as initial seed inputs. The full coverage report will be available in `generated/fuzz_coverage/coverage.html`.

Coverage for every PR is available in Circle in the "artifacts" tab of the coverage job. You will
need to navigate down and open "coverage.html" but then you can navigate per normal. NOTE: We
have seen some issues with seeing the artifacts tab. If you can't see it, log out of Circle, and
then log back in and it should start working.

The latest coverage report for master is available
[here](https://storage.googleapis.com/envoy-postsubmit/master/coverage/index.html).
[here](https://storage.googleapis.com/envoy-postsubmit/master/coverage/index.html). The latest fuzz coverage report for master is available [here](https://storage.googleapis.com/envoy-postsubmit/master/fuzz_coverage/index.html).

It's also possible to specialize the coverage build to a specified test or test dir. This is useful
when doing things like exploring the coverage of a fuzzer over its corpus. This can be done by
Expand Down
7 changes: 5 additions & 2 deletions bazel/coverage/fuzz_coverage_wrapper.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash

set -ex
set -x

TEST_BINARY=$1
shift
Expand All @@ -11,4 +11,7 @@ rm -rf fuzz_corpus
mkdir -p fuzz_corpus/seed_corpus
cp -r $@ fuzz_corpus/seed_corpus

${TEST_BINARY} fuzz_corpus -seed=${FUZZ_CORPUS_SEED:-1} -max_total_time=${FUZZ_CORPUS_TIME:-60}
# TODO(asraa): When fuzz targets are stable, remove error suppression and run coverage while fuzzing.
LLVM_PROFILE_FILE= ${TEST_BINARY} fuzz_corpus -seed=${FUZZ_CORPUS_SEED:-1} -max_total_time=${FUZZ_CORPUS_TIME:-60} -max_len=2048 || true

${TEST_BINARY} fuzz_corpus -runs=0
3 changes: 3 additions & 0 deletions ci/build_setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ mkdir -p "${ENVOY_DELIVERY_DIR}"
# This is where we copy the coverage report to.
export ENVOY_COVERAGE_ARTIFACT="${ENVOY_BUILD_DIR}"/generated/coverage.tar.gz

# This is where we copy the fuzz coverage report to.
export ENVOY_FUZZ_COVERAGE_ARTIFACT="${ENVOY_BUILD_DIR}"/generated/fuzz_coverage.tar.gz

# This is where we dump failed test logs for CI collection.
export ENVOY_FAILED_TEST_LOGS="${ENVOY_BUILD_DIR}"/generated/failed-testlogs
mkdir -p "${ENVOY_FAILED_TEST_LOGS}"
Expand Down
12 changes: 12 additions & 0 deletions ci/do_ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,18 @@ elif [[ "$CI_TARGET" == "bazel.coverage" ]]; then
test/run_envoy_bazel_coverage.sh ${COVERAGE_TEST_TARGETS}
collect_build_profile coverage
exit 0
elif [[ "$CI_TARGET" == "bazel.fuzz_coverage" ]]; then
setup_clang_toolchain
echo "bazel coverage build with fuzz tests ${COVERAGE_TEST_TARGETS}"

# Reduce the amount of memory Bazel tries to use to prevent it from launching too many subprocesses.
# This should prevent the system from running out of memory and killing tasks. See discussion on
# https://github.com/envoyproxy/envoy/pull/5611.
[ -z "$CIRCLECI" ] || export BAZEL_BUILD_OPTIONS="${BAZEL_BUILD_OPTIONS} --local_ram_resources=12288"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

FUZZ_COVERAGE=true test/run_envoy_bazel_coverage.sh ${COVERAGE_TEST_TARGETS}
collect_build_profile coverage
exit 0
elif [[ "$CI_TARGET" == "bazel.clang_tidy" ]]; then
setup_clang_toolchain
NUM_CPUS=$NUM_CPUS ci/run_clang_tidy.sh
Expand Down
10 changes: 9 additions & 1 deletion test/fuzz/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,15 @@ to provide fuzzers some interesting starting points for invalid inputs.
## Coverage reports

Coverage reports, where individual lines are annotated with fuzzing hit counts, are a useful way to
understand the scope and efficacy of the Envoy fuzzers. You can generate such reports from the
understand the scope and efficacy of the Envoy fuzzers. You can generate fuzz coverage reports both locally, and using the OSS-Fuzz infrastructure.

To generate fuzz coverage reports locally (see [Coverage builds](bazel/README.md), run
```
FUZZ_COVERAGE=true test/run_envoy_bazel_coverage.sh
```
This generates a coverage report after running the fuzz targets for one minute against the fuzzing engine libfuzzer and using the checked-in corpus as an initial seed.

Otherwise, you can generate reports from the
ClusterFuzz corpus following the general ClusterFuzz [instructions for profiling
setup](https://github.com/google/oss-fuzz/blob/master/docs/code_coverage.md).

Expand Down
19 changes: 14 additions & 5 deletions test/run_envoy_bazel_coverage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,14 @@ elif [[ -n "${COVERAGE_TARGET}" ]]; then
COVERAGE_TARGETS=${COVERAGE_TARGET}
else
# For fuzz builds, this overrides to just fuzz targets.
COVERAGE_TARGETS=//test/... && [[ ${FUZZ_COVERAGE} == "true" ]] &&
COVERAGE_TARGETS="$(bazel query 'attr("tags", "fuzz_target", //test/...)')"
COVERAGE_TARGETS=//test/...
fi

if [[ "${FUZZ_COVERAGE}" == "true" ]]; then

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This if has the same condition as the next if block. Can they be merged?

asraa marked this conversation as resolved.
Show resolved Hide resolved
COVERAGE_TARGETS=$(bazel query "attr("tags", "fuzz_target", ${COVERAGE_TARGETS})")
fi
echo "COVERAGE_TARGETS=${COVERAGE_TARGETS}"

if [[ "${FUZZ_COVERAGE}" == "true" ]]; then
BAZEL_BUILD_OPTIONS+=" --config=fuzz-coverage --test_tag_filters=-nocoverage"
else
Expand All @@ -36,7 +40,7 @@ bazel coverage ${BAZEL_BUILD_OPTIONS} ${COVERAGE_TARGETS}
[[ -z "${ENVOY_BUILD_PROFILE}" ]] || cp -f "$(bazel info output_base)/command.profile.gz" "${ENVOY_BUILD_PROFILE}/coverage.profile.gz" || true
[[ -z "${ENVOY_BUILD_DIR}" ]] || find bazel-testlogs/ -name test.log | tar zcf "${ENVOY_BUILD_DIR}/testlogs.tar.gz" -T -

COVERAGE_DIR="${SRCDIR}"/generated/coverage
COVERAGE_DIR="${SRCDIR}"/generated/coverage && [[ ${FUZZ_COVERAGE} == "true" ]] && COVERAGE_DIR="${SRCDIR}"/generated/fuzz_coverage

rm -rf "${COVERAGE_DIR}"
mkdir -p "${COVERAGE_DIR}"
Expand All @@ -47,7 +51,12 @@ cp bazel-out/_coverage/_coverage_report.dat "${COVERAGE_DATA}"
COVERAGE_VALUE=$(genhtml --prefix ${PWD} --output "${COVERAGE_DIR}" "${COVERAGE_DATA}" | tee /dev/stderr | grep lines... | cut -d ' ' -f 4)
COVERAGE_VALUE=${COVERAGE_VALUE%?}

[[ -z "${ENVOY_COVERAGE_ARTIFACT}" ]] || tar zcf "${ENVOY_COVERAGE_ARTIFACT}" -C ${COVERAGE_DIR} --transform 's/^\./coverage/' .
if [ "${FUZZ_COVERAGE}" == "true" ]
then
[[ -z "${ENVOY_FUZZ_COVERAGE_ARTIFACT}" ]] || tar zcf "${ENVOY_FUZZ_COVERAGE_ARTIFACT}" -C ${COVERAGE_DIR} --transform 's/^\./fuzz_coverage/' .
else
[[ -z "${ENVOY_COVERAGE_ARTIFACT}" ]] || tar zcf "${ENVOY_COVERAGE_ARTIFACT}" -C ${COVERAGE_DIR} --transform 's/^\./coverage/' .
fi

if [[ "$VALIDATE_COVERAGE" == "true" ]]; then
if [[ "${FUZZ_COVERAGE}" == "true" ]]; then
Expand All @@ -66,7 +75,7 @@ fi

# We want to allow per_file_coverage to fail without exiting this script.
set +e
if [[ "$VALIDATE_COVERAGE" == "true" ]]; then
if [[ "$VALIDATE_COVERAGE" == "true" ]] && [[ "{FUZZ_COVERAGE}" == "false"]]; then
echo "Checking per-extension coverage"
output=$(./test/per_file_coverage.sh)

Expand Down
1 change: 0 additions & 1 deletion test/server/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,6 @@ envoy_cc_fuzz_test(
"//test/integration:integration_lib",
"//test/mocks/server:options_mocks",
"//test/mocks/server:hot_restart_mocks",
"//test/mocks/stats:stats_mocks",
"//test/test_common:environment_lib",
] + select({
"//bazel:windows_x86_64": envoy_all_extensions(WINDOWS_SKIP_TARGETS),
Expand Down
138 changes: 138 additions & 0 deletions test/server/server_corpus/api_boost_crash

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.