Skip to content

[tools] initial fuzz coverage script#10289

Merged
htuch merged 17 commits intoenvoyproxy:masterfrom
asraa:fuzz-coverage
May 3, 2020
Merged

[tools] initial fuzz coverage script#10289
htuch merged 17 commits intoenvoyproxy:masterfrom
asraa:fuzz-coverage

Conversation

@asraa
Copy link
Copy Markdown
Contributor

@asraa asraa commented Mar 6, 2020

Fuzz coverage script to run all fuzz targets (or ones specified) for 1 min creating a temporary corpus for testcases with new coverage, and then runs a coverage script over all the binaries produced from bazel coverage.

usage:
test/run_envoy_fuzz_coverage.sh (runs all fuzz targets)
test/run_envoy_fuzz_coverage.sh //test/common/common:base64_fuzz_test //test/common/common:hash_fuzz_test (runs just specified)

Risk level: Low
Testing: Local

Signed-off-by: Asra Ali asraa@google.com

Signed-off-by: Asra Ali <asraa@google.com>
@asraa
Copy link
Copy Markdown
Contributor Author

asraa commented Mar 6, 2020

/review @htuch

Questions:

  • Was trying to minimize # of targets built. Bazel reports it discards crash when I change the --test_arg. It seems like I can't avoid building the fuzz running target and the corresponding coverage one separately

@repokitteh-read-only repokitteh-read-only bot requested a review from htuch March 6, 2020 18:58
Signed-off-by: Asra Ali <asraa@google.com>
@htuch htuch assigned htuch and lizan Mar 8, 2020
@htuch htuch requested a review from lizan March 8, 2020 20:58
Copy link
Copy Markdown
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

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

This is super awesome, really looking forward to being able to gate commits on fuzz coverage and the flow here makes a lot of sense (generate tmp corpus from real fuzz runs, then do a normal coverage build).

if [[ $# -gt 0 ]]; then
FUZZ_TARGETS=$*
else
# By default, this will be all fuzz targets.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Something like this also exists in the OSS-fuzz runner script. Could we define this in a common bash utility script and import it in both locations?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

What do you think of the tag? makes it an easy bazel query

echo "Building fuzz targets..."
for t in ${FUZZ_TARGETS}
do
bazel build "${t}_with_libfuzzer" --config asan-fuzzer -c opt
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you do a single build invocation by listing all the targets on the bazel build CLI? That should be faster.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done

for t in ${FUZZ_TARGETS}
do
# Get the original corpus for the fuzz target
ORIGINAL_CORPUS=$(bazel query "labels(srcs, ${t}_corpus)" | head -1)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Does this work for a generated corpus?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, modified to pull data attribute, so now it works for something like route fuzz test

done

# Wait for background process to run.
# TODO? Processes will still run in background if user ctrl-c.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Consider adding trap handlers, see the trap Bash builtin.

@htuch
Copy link
Copy Markdown
Member

htuch commented Mar 8, 2020

@lizan probably should also give this a pass once it's ready to ship.

Copy link
Copy Markdown
Member

@lizan lizan left a comment

Choose a reason for hiding this comment

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

I see a lot of duplication from the coverage script, is it possible to reuse possible parts from there? Or, use a environment var or parameter to control that script to generate fuzz before run coverage?

htuch pushed a commit that referenced this pull request Mar 13, 2020
I'm seeing a failure in OSS-Fuzz build, as well as fuzz CI tool #10289 due to fuzzing build macro FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION.

Basically, PR #10050 introduced regex rewrites that are tested in config_impl_test, which is executed to create the corpus for route_fuzz_test. Fuzz builds are built with the FUZZING_BUILD_MODE... macro, and the RE2 library that does the regex rewrites in the test only does single replacements in fuzzing mode rather than the global replacement in the tests, so the test fails, and the fuzz build fails.

This change defined FUZZING_BUILD_MODE... only for fuzzing build rules, and explicitly undefines them for the config_impl_test.

RE OSS-Fuzz builds, this is odd. Bazel CLI flags take precedence, so I'm not sure what to do when we build in that environment. I can't seem to #undef in the tests, but I need to come up with some solution.I don't like manually removing the CLI flag in our build script, but maybe? https://github.com/google/oss-fuzz/blob/66e0e379395d3a3ee741b08f4d306e1ed71c4003/infra/base-images/base-clang/Dockerfile

Testing: bazel build //test/common/router:route_fuzz_test_with_libfuzzer --config=asan-fuzzer

Signed-off-by: Asra Ali <asraa@google.com>
asraa added 4 commits March 16, 2020 12:05
Signed-off-by: Asra Ali <asraa@google.com>
Signed-off-by: Asra Ali <asraa@google.com>
Signed-off-by: Asra Ali <asraa@google.com>
Signed-off-by: Asra Ali <asraa@google.com>
TEMP_CORPORA+="${CORPUS_DIR} "
# Run fuzzing process.
TARGET_BINARY="${t/://}"
bazel-bin/${TARGET_BINARY:2}_with_libfuzzer -max_total_time=60 ${CORPUS_DIR} $(pwd)${ORIGINAL_CORPUS:1} &
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: some unescaped expansions.

@htuch
Copy link
Copy Markdown
Member

htuch commented Mar 17, 2020

The convergence with the coverage script looks really nice!

Signed-off-by: Asra Ali <asraa@google.com>
Copy link
Copy Markdown
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

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

Other than various nits and @lizan comment, this LGTM.
/wait

asraa added 2 commits March 25, 2020 15:19
Signed-off-by: Asra Ali <asraa@google.com>
Signed-off-by: Asra Ali <asraa@google.com>
@asraa
Copy link
Copy Markdown
Contributor Author

asraa commented Mar 26, 2020

Fixed up the rest of the comments + tested with full and partial runs of the fuzz mode and regular mode...

I did change the script to build and run fuzz targets to not exit if it fails, the reason is sometimes the fuzz targets find unrelated blockers (for eg ones on OSS-Fuzz) within the 60 seconds, and I don't think we want to totally block devs from submission if the coverage script fails from an existing bug it finds. wdyt?

Signed-off-by: Asra Ali <asraa@google.com>
@htuch
Copy link
Copy Markdown
Member

htuch commented Mar 27, 2020

@asraa seems fine to power on thru those failure although one day I would hope we can remove that; ultimately the main thing we want is to be able to gate on coverage here.

Copy link
Copy Markdown
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

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

LGTM modulo comments, will leave it with @lizan for final review and merge, thanks!

LIBFUZZER_TARGETS+="${t}_with_libfuzzer "
done

bazel build ${LIBFUZZER_TARGETS} --config asan-fuzzer -c opt
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should we be using ${BAZEL_BUiLD_OPTIONS} here @lizan ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yes unless there's reason not to do so.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ping?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done! Sorry about that

TARGET="${t}_with_libfuzzer"
else
TEST_ARGS=(--test_arg="--log-path /dev/null" --test_arg="-l trace")
OBJECTS="bazel-bin/test/coverage/coverage_tests"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It feels like this should be outside the loop, as it's only done once.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

For clarity? In the case that it's just coverage_tests the loop only has one item.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yeah, maybe. I don't feel that strongly, it just took a somewhat higher cognitive hit processing that code in the loop :)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Hm to resolve, I added a comment addressing the loop -- what I didn't want was to copy/paste the bazel command per loop, but if that makes more sense let me know!

@stale
Copy link
Copy Markdown

stale bot commented Apr 7, 2020

This pull request has been automatically marked as stale because it has not had activity in the last 7 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions!

@stale stale bot added the stale stalebot believes this issue/PR has not been touched recently label Apr 7, 2020
Signed-off-by: Asra Ali <asraa@google.com>
@stale stale bot removed the stale stalebot believes this issue/PR has not been touched recently label Apr 7, 2020
@htuch
Copy link
Copy Markdown
Member

htuch commented Apr 7, 2020

@lizan any final comments before merging?

@stale
Copy link
Copy Markdown

stale bot commented Apr 14, 2020

This pull request has been automatically marked as stale because it has not had activity in the last 7 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions!

@stale stale bot added stale stalebot believes this issue/PR has not been touched recently and removed stale stalebot believes this issue/PR has not been touched recently labels Apr 14, 2020
Copy link
Copy Markdown
Member

@lizan lizan left a comment

Choose a reason for hiding this comment

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

Sorry for the delay, can you merge master?

asraa added 3 commits April 16, 2020 10:10
@asraa
Copy link
Copy Markdown
Contributor Author

asraa commented Apr 21, 2020

All set -- sorry there were a couple coverage related PRs submitted very recently

@htuch
Copy link
Copy Markdown
Member

htuch commented Apr 22, 2020

LGTM, will let @lizan do final approval and merge.

Signed-off-by: Asra Ali <asraa@google.com>
@stale
Copy link
Copy Markdown

stale bot commented Apr 29, 2020

This pull request has been automatically marked as stale because it has not had activity in the last 7 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions!

@stale stale bot added the stale stalebot believes this issue/PR has not been touched recently label Apr 29, 2020
@lizan
Copy link
Copy Markdown
Member

lizan commented Apr 29, 2020

@asraa can you check CI?

@stale stale bot removed the stale stalebot believes this issue/PR has not been touched recently label Apr 29, 2020
Signed-off-by: Asra Ali <asraa@google.com>
@asraa
Copy link
Copy Markdown
Contributor Author

asraa commented Apr 29, 2020

On it -- need to figure out why coverage script seems to have a regression on master when testing locally.

Signed-off-by: Asra Ali <asraa@google.com>
@asraa
Copy link
Copy Markdown
Contributor Author

asraa commented Apr 30, 2020

I couldn't repro locally with docker bazel.coverage or locally with test/run_envoy_bazel_coverage.sh.

@asraa
Copy link
Copy Markdown
Contributor Author

asraa commented May 1, 2020

friendly ping @lizan -- looks like it's passing CI

@htuch htuch merged commit 28af32e into envoyproxy:master May 3, 2020
@asraa asraa deleted the fuzz-coverage branch May 4, 2020 13:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants