mirror of https://github.com/google/oss-fuzz.git
Centipede's CI build, trial build, and build tests (#8422)
Adding CI build, trial build, and build tests. Co-authored-by: Oliver Chang <oliverchang@users.noreply.github.com>
This commit is contained in:
parent
0a98805261
commit
2fa71e3c7f
|
@ -114,7 +114,16 @@ function check_engine {
|
|||
cat $FUZZER_OUTPUT
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
elif [[ "$FUZZING_ENGINE" == centipede && "$SANITIZER" == "none" ]]; then
|
||||
# Only perform run test on unsanitized binary for now.
|
||||
# TODO(Dongge): Support run test for sanitized binaries as well.
|
||||
timeout --preserve-status -s INT 20s run_fuzzer $FUZZER_NAME &>$FUZZER_OUTPUT
|
||||
CHECK_PASSED=$(egrep "\[0] begin-fuzz: ft: 0 cov: 0" -c $FUZZER_OUTPUT)
|
||||
if (( $CHECK_PASSED == 0 )); then
|
||||
echo "BAD BUILD: fuzzing $FUZZER with centipede failed."
|
||||
cat $FUZZER_OUTPUT
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# TODO: add checks for other fuzzing engines if possible.
|
||||
|
|
|
@ -72,6 +72,16 @@ function get_dictionary() {
|
|||
fi
|
||||
}
|
||||
|
||||
function get_extra_binaries() {
|
||||
[[ "$FUZZING_ENGINE" != "centipede" ]] && return
|
||||
|
||||
extra_binaries="$OUT/**_${SANITIZER}/${FUZZER}"
|
||||
if compgen -G "$extra_binaries" >> /dev/null; then
|
||||
printf -- "--extra_binaries %s" \""$extra_binaries\""
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
rm -rf $FUZZER_OUT && mkdir -p $FUZZER_OUT
|
||||
|
||||
SEED_CORPUS="${FUZZER}_seed_corpus.zip"
|
||||
|
@ -177,7 +187,7 @@ elif [[ "$FUZZING_ENGINE" = centipede ]]; then
|
|||
# --address_space_limit_mb=0: No address space limit.
|
||||
# --binary: The target binary under test without sanitizer.
|
||||
# --extra_binary: The target binaries under test with sanitizers.
|
||||
CMD_LINE="$OUT/centipede --workdir=\"$OUT/workdir\" --corpus_dir=\"$CORPUS_DIR\" --fork_server=1 --exit_on_crash=1 --timeout=1200 --rss_limit_mb=4096 --address_space_limit_mb=0 $(get_dictionary) --binary=\"$OUT/${FUZZER}\" --extra_binaries=\"$OUT/**_${SANITIZER}/${FUZZER}\" $*"
|
||||
CMD_LINE="$OUT/centipede --workdir=\"$OUT/workdir\" --corpus_dir=\"$CORPUS_DIR\" --fork_server=1 --exit_on_crash=1 --timeout=1200 --rss_limit_mb=4096 --address_space_limit_mb=0 $(get_dictionary) --binary=\"$OUT/${FUZZER}\" $(get_extra_binaries) $*"
|
||||
else
|
||||
|
||||
CMD_LINE="$OUT/$FUZZER $FUZZER_ARGS $*"
|
||||
|
|
|
@ -75,7 +75,7 @@ ENGINE_INFO = {
|
|||
supported_architectures=['x86_64']),
|
||||
'centipede':
|
||||
EngineInfo(upload_bucket='clusterfuzz-builds-centipede',
|
||||
supported_sanitizers=['address'],
|
||||
supported_sanitizers=['address', 'none'],
|
||||
supported_architectures=['x86_64']),
|
||||
}
|
||||
|
||||
|
|
|
@ -115,6 +115,14 @@ def get_sanitizer_strings(sanitizers):
|
|||
return processed_sanitizers
|
||||
|
||||
|
||||
def set_default_sanitizer_for_centipede(project_yaml):
|
||||
"""Adds none as a sanitizer for centipede in yaml if it does not exist yet."""
|
||||
# Centipede requires a separate unsanitized binary to use sanitized ones.
|
||||
if ('centipede' in project_yaml['fuzzing_engines'] and
|
||||
project_yaml['sanitizers'] and 'none' not in project_yaml['sanitizers']):
|
||||
project_yaml['sanitizers'].append('none')
|
||||
|
||||
|
||||
class Project: # pylint: disable=too-many-instance-attributes
|
||||
"""Class representing an OSS-Fuzz project."""
|
||||
|
||||
|
@ -164,6 +172,9 @@ def set_yaml_defaults(project_yaml):
|
|||
project_yaml.setdefault('run_tests', True)
|
||||
project_yaml.setdefault('coverage_extra_args', '')
|
||||
project_yaml.setdefault('labels', {})
|
||||
# Adds 'none' as a sanitizer for centipede to the project yaml by default,
|
||||
# because Centipede always requires a separate build of unsanitized binary.
|
||||
set_default_sanitizer_for_centipede(project_yaml)
|
||||
|
||||
|
||||
def is_supported_configuration(build):
|
||||
|
|
|
@ -75,6 +75,42 @@ class TestRequestCoverageBuilds(fake_filesystem_unittest.TestCase):
|
|||
config)
|
||||
self.assertEqual(build_steps, expected_build_steps)
|
||||
|
||||
@mock.patch('build_lib.get_signed_url', return_value='test_url')
|
||||
@mock.patch('build_project.get_datetime_now',
|
||||
return_value=test_utils.FAKE_DATETIME)
|
||||
def test_get_centipede_build_steps(self, mock_url, mock_get_datetime_now):
|
||||
"""Test for get_build_steps of centipede."""
|
||||
del mock_url, mock_get_datetime_now
|
||||
# The none sanitizer should be added automatically when other sanitizers are
|
||||
# specified by the users.
|
||||
project_yaml_contents = (
|
||||
'language: c++\n'
|
||||
'fuzzing_engines:\n'
|
||||
' - centipede\n'
|
||||
'sanitizers:\n'
|
||||
' - address\n'
|
||||
'architectures:\n'
|
||||
' - x86_64\n'
|
||||
'main_repo: https://github.com/google/centipede.git\n')
|
||||
self.fs.create_dir(test_utils.PROJECT_DIR)
|
||||
test_utils.create_project_data(test_utils.PROJECT, project_yaml_contents)
|
||||
|
||||
expected_build_steps_file_path = test_utils.get_test_data_file_path(
|
||||
'expected_centipede_build_steps.json')
|
||||
self.fs.add_real_file(expected_build_steps_file_path)
|
||||
with open(expected_build_steps_file_path) as expected_build_steps_file:
|
||||
expected_build_steps = json.load(expected_build_steps_file)
|
||||
|
||||
config = build_project.Config(False, False, None, False, True)
|
||||
project_yaml, dockerfile = build_project.get_project_data(
|
||||
test_utils.PROJECT)
|
||||
build_steps = build_project.get_build_steps(test_utils.PROJECT,
|
||||
project_yaml, dockerfile,
|
||||
test_utils.IMAGE_PROJECT,
|
||||
test_utils.BASE_IMAGES_PROJECT,
|
||||
config)
|
||||
self.assertEqual(build_steps, expected_build_steps)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=False)
|
||||
|
|
|
@ -0,0 +1,308 @@
|
|||
[
|
||||
{
|
||||
"args": [
|
||||
"clone",
|
||||
"https://github.com/google/oss-fuzz.git",
|
||||
"--depth",
|
||||
"1"
|
||||
],
|
||||
"name": "gcr.io/cloud-builders/git"
|
||||
},
|
||||
{
|
||||
"name": "gcr.io/cloud-builders/docker",
|
||||
"args": [
|
||||
"build",
|
||||
"--tag",
|
||||
"gcr.io/oss-fuzz/test-project",
|
||||
"."
|
||||
],
|
||||
"dir": "oss-fuzz/projects/test-project"
|
||||
},
|
||||
{
|
||||
"name": "gcr.io/oss-fuzz/test-project",
|
||||
"args": [
|
||||
"bash",
|
||||
"-c",
|
||||
"srcmap > /workspace/srcmap.json && cat /workspace/srcmap.json"
|
||||
],
|
||||
"env": [
|
||||
"OSSFUZZ_REVISION=$REVISION_ID",
|
||||
"FUZZING_LANGUAGE=c++"
|
||||
],
|
||||
"id": "srcmap"
|
||||
},
|
||||
{
|
||||
"name": "gcr.io/cloud-builders/docker",
|
||||
"env": [
|
||||
"ARCHITECTURE=x86_64",
|
||||
"FUZZING_ENGINE=centipede",
|
||||
"FUZZING_LANGUAGE=c++",
|
||||
"HOME=/root",
|
||||
"OUT=/workspace/out/centipede-address-x86_64",
|
||||
"SANITIZER=address"
|
||||
],
|
||||
"args": [
|
||||
"run",
|
||||
"--platform",
|
||||
"linux/amd64",
|
||||
"-v",
|
||||
"/workspace:/workspace",
|
||||
"-e",
|
||||
"ARCHITECTURE=x86_64",
|
||||
"-e",
|
||||
"FUZZING_ENGINE=centipede",
|
||||
"-e",
|
||||
"FUZZING_LANGUAGE=c++",
|
||||
"-e",
|
||||
"HOME=/root",
|
||||
"-e",
|
||||
"OUT=/workspace/out/centipede-address-x86_64",
|
||||
"-e",
|
||||
"SANITIZER=address",
|
||||
"-t",
|
||||
"gcr.io/oss-fuzz/test-project",
|
||||
"bash",
|
||||
"-c",
|
||||
"rm -r /out && cd /src && cd /src && mkdir -p /workspace/out/centipede-address-x86_64 && compile || (echo \"********************************************************************************\nFailed to build.\nTo reproduce, run:\npython infra/helper.py build_image test-project\npython infra/helper.py build_fuzzers --sanitizer address --engine centipede --architecture x86_64 test-project\n********************************************************************************\" && false)"
|
||||
],
|
||||
"id": "compile-centipede-address-x86_64"
|
||||
},
|
||||
{
|
||||
"name": "gcr.io/cloud-builders/docker",
|
||||
"env": [
|
||||
"ARCHITECTURE=x86_64",
|
||||
"FUZZING_ENGINE=centipede",
|
||||
"FUZZING_LANGUAGE=c++",
|
||||
"HOME=/root",
|
||||
"OUT=/workspace/out/centipede-address-x86_64",
|
||||
"SANITIZER=address"
|
||||
],
|
||||
"args": [
|
||||
"run",
|
||||
"--platform",
|
||||
"linux/amd64",
|
||||
"-v",
|
||||
"/workspace:/workspace",
|
||||
"-e",
|
||||
"ARCHITECTURE=x86_64",
|
||||
"-e",
|
||||
"FUZZING_ENGINE=centipede",
|
||||
"-e",
|
||||
"FUZZING_LANGUAGE=c++",
|
||||
"-e",
|
||||
"HOME=/root",
|
||||
"-e",
|
||||
"OUT=/workspace/out/centipede-address-x86_64",
|
||||
"-e",
|
||||
"SANITIZER=address",
|
||||
"-t",
|
||||
"gcr.io/oss-fuzz-base/base-runner",
|
||||
"bash",
|
||||
"-c",
|
||||
"test_all.py || (echo \"********************************************************************************\nBuild checks failed.\nTo reproduce, run:\npython infra/helper.py build_image test-project\npython infra/helper.py build_fuzzers --sanitizer address --engine centipede --architecture x86_64 test-project\npython infra/helper.py check_build --sanitizer address --engine centipede --architecture x86_64 test-project\n********************************************************************************\" && false)"
|
||||
],
|
||||
"id": "build-check-centipede-address-x86_64"
|
||||
},
|
||||
{
|
||||
"name": "gcr.io/oss-fuzz-base/base-runner",
|
||||
"env": [
|
||||
"ARCHITECTURE=x86_64",
|
||||
"FUZZING_ENGINE=centipede",
|
||||
"FUZZING_LANGUAGE=c++",
|
||||
"HOME=/root",
|
||||
"OUT=/workspace/out/centipede-address-x86_64",
|
||||
"SANITIZER=address"
|
||||
],
|
||||
"args": [
|
||||
"bash",
|
||||
"-c",
|
||||
"targets_list > /workspace/targets.list.address"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gcr.io/oss-fuzz/test-project",
|
||||
"args": [
|
||||
"bash",
|
||||
"-c",
|
||||
"cd /workspace/out/centipede-address-x86_64 && zip -r test-project-address-202001010000.zip *"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gcr.io/oss-fuzz-base/uploader",
|
||||
"args": [
|
||||
"/workspace/srcmap.json",
|
||||
"test_url"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gcr.io/oss-fuzz-base/uploader",
|
||||
"args": [
|
||||
"/workspace/out/centipede-address-x86_64/test-project-address-202001010000.zip",
|
||||
"test_url"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gcr.io/oss-fuzz-base/uploader",
|
||||
"args": [
|
||||
"/workspace/targets.list.address",
|
||||
"test_url"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gcr.io/cloud-builders/curl",
|
||||
"args": [
|
||||
"-H",
|
||||
"Content-Type: text/plain",
|
||||
"-X",
|
||||
"PUT",
|
||||
"-d",
|
||||
"test-project-address-202001010000.zip",
|
||||
"test_url"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gcr.io/oss-fuzz/test-project",
|
||||
"args": [
|
||||
"bash",
|
||||
"-c",
|
||||
"rm -r /workspace/out/centipede-address-x86_64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gcr.io/cloud-builders/docker",
|
||||
"env": [
|
||||
"ARCHITECTURE=x86_64",
|
||||
"FUZZING_ENGINE=centipede",
|
||||
"FUZZING_LANGUAGE=c++",
|
||||
"HOME=/root",
|
||||
"OUT=/workspace/out/centipede-none-x86_64",
|
||||
"SANITIZER=none"
|
||||
],
|
||||
"args": [
|
||||
"run",
|
||||
"--platform",
|
||||
"linux/amd64",
|
||||
"-v",
|
||||
"/workspace:/workspace",
|
||||
"-e",
|
||||
"ARCHITECTURE=x86_64",
|
||||
"-e",
|
||||
"FUZZING_ENGINE=centipede",
|
||||
"-e",
|
||||
"FUZZING_LANGUAGE=c++",
|
||||
"-e",
|
||||
"HOME=/root",
|
||||
"-e",
|
||||
"OUT=/workspace/out/centipede-none-x86_64",
|
||||
"-e",
|
||||
"SANITIZER=none",
|
||||
"-t",
|
||||
"gcr.io/oss-fuzz/test-project",
|
||||
"bash",
|
||||
"-c",
|
||||
"rm -r /out && cd /src && cd /src && mkdir -p /workspace/out/centipede-none-x86_64 && compile || (echo \"********************************************************************************\nFailed to build.\nTo reproduce, run:\npython infra/helper.py build_image test-project\npython infra/helper.py build_fuzzers --sanitizer none --engine centipede --architecture x86_64 test-project\n********************************************************************************\" && false)"
|
||||
],
|
||||
"id": "compile-centipede-none-x86_64"
|
||||
},
|
||||
{
|
||||
"name": "gcr.io/cloud-builders/docker",
|
||||
"env": [
|
||||
"ARCHITECTURE=x86_64",
|
||||
"FUZZING_ENGINE=centipede",
|
||||
"FUZZING_LANGUAGE=c++",
|
||||
"HOME=/root",
|
||||
"OUT=/workspace/out/centipede-none-x86_64",
|
||||
"SANITIZER=none"
|
||||
],
|
||||
"args": [
|
||||
"run",
|
||||
"--platform",
|
||||
"linux/amd64",
|
||||
"-v",
|
||||
"/workspace:/workspace",
|
||||
"-e",
|
||||
"ARCHITECTURE=x86_64",
|
||||
"-e",
|
||||
"FUZZING_ENGINE=centipede",
|
||||
"-e",
|
||||
"FUZZING_LANGUAGE=c++",
|
||||
"-e",
|
||||
"HOME=/root",
|
||||
"-e",
|
||||
"OUT=/workspace/out/centipede-none-x86_64",
|
||||
"-e",
|
||||
"SANITIZER=none",
|
||||
"-t",
|
||||
"gcr.io/oss-fuzz-base/base-runner",
|
||||
"bash",
|
||||
"-c",
|
||||
"test_all.py || (echo \"********************************************************************************\nBuild checks failed.\nTo reproduce, run:\npython infra/helper.py build_image test-project\npython infra/helper.py build_fuzzers --sanitizer none --engine centipede --architecture x86_64 test-project\npython infra/helper.py check_build --sanitizer none --engine centipede --architecture x86_64 test-project\n********************************************************************************\" && false)"
|
||||
],
|
||||
"id": "build-check-centipede-none-x86_64"
|
||||
},
|
||||
{
|
||||
"name": "gcr.io/oss-fuzz-base/base-runner",
|
||||
"env": [
|
||||
"ARCHITECTURE=x86_64",
|
||||
"FUZZING_ENGINE=centipede",
|
||||
"FUZZING_LANGUAGE=c++",
|
||||
"HOME=/root",
|
||||
"OUT=/workspace/out/centipede-none-x86_64",
|
||||
"SANITIZER=none"
|
||||
],
|
||||
"args": [
|
||||
"bash",
|
||||
"-c",
|
||||
"targets_list > /workspace/targets.list.none"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gcr.io/oss-fuzz/test-project",
|
||||
"args": [
|
||||
"bash",
|
||||
"-c",
|
||||
"cd /workspace/out/centipede-none-x86_64 && zip -r test-project-none-202001010000.zip *"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gcr.io/oss-fuzz-base/uploader",
|
||||
"args": [
|
||||
"/workspace/srcmap.json",
|
||||
"test_url"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gcr.io/oss-fuzz-base/uploader",
|
||||
"args": [
|
||||
"/workspace/out/centipede-none-x86_64/test-project-none-202001010000.zip",
|
||||
"test_url"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gcr.io/oss-fuzz-base/uploader",
|
||||
"args": [
|
||||
"/workspace/targets.list.none",
|
||||
"test_url"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gcr.io/cloud-builders/curl",
|
||||
"args": [
|
||||
"-H",
|
||||
"Content-Type: text/plain",
|
||||
"-X",
|
||||
"PUT",
|
||||
"-d",
|
||||
"test-project-none-202001010000.zip",
|
||||
"test_url"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gcr.io/oss-fuzz/test-project",
|
||||
"args": [
|
||||
"bash",
|
||||
"-c",
|
||||
"rm -r /workspace/out/centipede-none-x86_64"
|
||||
]
|
||||
}
|
||||
]
|
|
@ -109,7 +109,7 @@ def get_args(args=None):
|
|||
help='Sanitizers.')
|
||||
parser.add_argument('--fuzzing-engines',
|
||||
required=False,
|
||||
default=['afl', 'libfuzzer', 'honggfuzz'],
|
||||
default=['afl', 'libfuzzer', 'honggfuzz', 'centipede'],
|
||||
nargs='+',
|
||||
help='Fuzzing engines.')
|
||||
parser.add_argument('--branch',
|
||||
|
|
|
@ -68,7 +68,7 @@ class TestShouldBuild(unittest.TestCase):
|
|||
|
||||
def test_libfuzzer_coverage_build(self):
|
||||
"""Tests that should_build returns True for coverage build of a project
|
||||
specifying 'libfuzzer' and for fuzzing_engines."""
|
||||
specifying 'libfuzzer' for fuzzing_engines."""
|
||||
_set_coverage_build()
|
||||
project_yaml = {
|
||||
'language': 'c++',
|
||||
|
@ -79,7 +79,7 @@ class TestShouldBuild(unittest.TestCase):
|
|||
|
||||
def test_go_coverage_build(self):
|
||||
"""Tests that should_build returns True for coverage build of a project
|
||||
specifying 'libfuzzer' and for fuzzing_engines."""
|
||||
specifying 'libfuzzer' for fuzzing_engines."""
|
||||
_set_coverage_build()
|
||||
project_yaml = {'language': 'go'}
|
||||
self.assertTrue(build.should_build(project_yaml))
|
||||
|
@ -96,3 +96,29 @@ class TestShouldBuild(unittest.TestCase):
|
|||
'sanitizers': ['address']
|
||||
}
|
||||
self.assertFalse(build.should_build(project_yaml))
|
||||
|
||||
def test_centipede_none_build(self):
|
||||
"""Tests that should_build returns True for none sanitizer build of a
|
||||
project specifying 'centipede' for fuzzing_engines."""
|
||||
os.environ['SANITIZER'] = 'none'
|
||||
os.environ['ENGINE'] = 'centipede'
|
||||
os.environ['ARCHITECTURE'] = 'x86_64'
|
||||
project_yaml = {
|
||||
'language': 'c++',
|
||||
'fuzzing_engines': ['centipede'],
|
||||
'sanitizers': ['none']
|
||||
}
|
||||
self.assertTrue(build.should_build(project_yaml))
|
||||
|
||||
def test_centipede_address_build(self):
|
||||
"""Tests that should_build returns True for address sanitizer build of a
|
||||
project specifying 'centipede' for fuzzing_engines."""
|
||||
os.environ['SANITIZER'] = 'address'
|
||||
os.environ['ENGINE'] = 'centipede'
|
||||
os.environ['ARCHITECTURE'] = 'x86_64'
|
||||
project_yaml = {
|
||||
'language': 'c++',
|
||||
'fuzzing_engines': ['centipede'],
|
||||
'sanitizers': ['address']
|
||||
}
|
||||
self.assertTrue(build.should_build(project_yaml))
|
||||
|
|
|
@ -746,14 +746,6 @@ def _add_oss_fuzz_ci_if_needed(env):
|
|||
env.append('OSS_FUZZ_CI=' + oss_fuzz_ci)
|
||||
|
||||
|
||||
def get_target_out_dir(args):
|
||||
"""Change the out/ to a subdir when building wth Centipede and sanitizers"""
|
||||
if args.engine == 'centipede' and args.sanitizer != 'none':
|
||||
return os.path.join(args.project.out,
|
||||
f'{args.project.name}_{args.sanitizer}')
|
||||
return args.project.out
|
||||
|
||||
|
||||
def check_build(args):
|
||||
"""Checks that fuzzers in the container execute without errors."""
|
||||
if not check_project_exists(args.project):
|
||||
|
@ -773,10 +765,8 @@ def check_build(args):
|
|||
if args.e:
|
||||
env += args.e
|
||||
|
||||
target_dir = get_target_out_dir(args)
|
||||
|
||||
run_args = _env_to_docker_args(env) + [
|
||||
'-v', f'{target_dir}:/out', '-t', BASE_RUNNER_IMAGE
|
||||
'-v', f'{args.project.out}:/out', '-t', BASE_RUNNER_IMAGE
|
||||
]
|
||||
|
||||
if args.fuzzer_name:
|
||||
|
|
Loading…
Reference in New Issue