From 43fd25f26accbd4f0794b9d025717dc0b034cd79 Mon Sep 17 00:00:00 2001 From: Abhishek Arya Date: Sun, 29 Apr 2018 18:44:22 -0700 Subject: [PATCH] Add check_build command to infra/helper.py (Fix #1356) (#1379) * Add check_build command to infra/helper.py * Add exit message. --- infra/base-images/base-runner/bad_build_check | 8 +-- infra/helper.py | 49 +++++++++++++++++++ 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/infra/base-images/base-runner/bad_build_check b/infra/base-images/base-runner/bad_build_check index 560fa0373..515c69b5c 100755 --- a/infra/base-images/base-runner/bad_build_check +++ b/infra/base-images/base-runner/bad_build_check @@ -48,7 +48,7 @@ function check_instrumentation { $FUZZER -runs=$MIN_NUMBER_OF_RUNS &>$FUZZER_OUTPUT CHECK_FAILED=$(egrep "ERROR: no interesting inputs were found. Is the code instrumented" -c $FUZZER_OUTPUT) if (( $CHECK_FAILED > 0 )); then - echo "BAD BUILD: the target does not seem to have coverage instrumentation." + echo "BAD BUILD: $FUZZER does not seem to have coverage instrumentation." # Bail out as the further check does not make any sense, there are 0 PCs. return 1 @@ -57,7 +57,7 @@ function check_instrumentation { local NUMBER_OF_EDGES=$(grep -Po "INFO: Loaded [[:digit:]]+ module.*\(.*(counters|guards)\):[[:space:]]+\K[[:digit:]]+" $FUZZER_OUTPUT) if (( $NUMBER_OF_EDGES < $THRESHOLD_FOR_NUMBER_OF_EDGES )); then - echo "BAD BUILD: the target seems to have only partial coverage instrumentation." + echo "BAD BUILD: $FUZZER seems to have only partial coverage instrumentation." fi } @@ -74,7 +74,7 @@ function check_startup_crash { fi if [ "$CHECK_PASSED" -eq "0" ]; then - echo "BAD BUILD: the fuzzer seems to have either startup crash or exit." + echo "BAD BUILD: $FUZZER seems to have either startup crash or exit." fi } @@ -184,7 +184,7 @@ function check_seed_corpus { # Don't output anything if fuzz target hasn't crashed. if [ $? -ne 0 ]; then - echo "$FUZZER_NAME has a crash input in its seed coprpus:" + echo "BAD BUILD: $FUZZER has a crashing input in its seed corpus:" cat $FUZZER_OUTPUT fi } diff --git a/infra/helper.py b/infra/helper.py index c5784c33d..4159ebeae 100755 --- a/infra/helper.py +++ b/infra/helper.py @@ -72,6 +72,15 @@ def main(): build_fuzzers_parser.add_argument('source_path', help='path of local source', nargs='?') + check_build_parser = subparsers.add_parser( + 'check_build', help='Checks that fuzzers execute without errors.') + _add_engine_args(check_build_parser) + _add_sanitizer_args(check_build_parser) + _add_environment_args(check_build_parser) + check_build_parser.add_argument('project_name', help='name of the project') + check_build_parser.add_argument('fuzzer_name', help='name of the fuzzer', + nargs='?') + run_fuzzer_parser = subparsers.add_parser( 'run_fuzzer', help='Run a fuzzer.') _add_engine_args(run_fuzzer_parser) @@ -118,6 +127,8 @@ def main(): return build_image(args) elif args.command == 'build_fuzzers': return build_fuzzers(args) + elif args.command == 'check_build': + return check_build(args) elif args.command == 'run_fuzzer': return run_fuzzer(args) elif args.command == 'coverage': @@ -326,6 +337,44 @@ def build_fuzzers(args): return 0 +def check_build(args): + """Checks that fuzzers in the container execute without errors.""" + if not _check_project_exists(args.project_name): + return 1 + + if (args.fuzzer_name and + not _check_fuzzer_exists(args.project_name, args.fuzzer_name)): + return 1 + + env = [ + 'FUZZING_ENGINE=' + args.engine, + 'SANITIZER=' + args.sanitizer + ] + if args.e: + env += args.e + + run_args = sum([['-e', v] for v in env], []) + [ + '-v', '%s:/out' % os.path.join(BUILD_DIR, 'out', args.project_name), + '-t', 'gcr.io/oss-fuzz-base/base-runner' + ] + + if args.fuzzer_name: + run_args += [ + 'bad_build_check', + os.path.join('/out', args.fuzzer_name) + ] + else: + run_args.append('test_all') + + exit_code = docker_run(run_args) + if exit_code == 0: + print('Check build passed.') + else: + print('Check build failed.') + + return exit_code + + def run_fuzzer(args): """Runs a fuzzer in the container.""" if not _check_project_exists(args.project_name):