Skip to content

Commit ef93cca

Browse files
committed
cifuzzer: provide fuzzing_engine parameter
It is mildly bad that it is currently impossible to actually CI all of the builds the oss-fuzz proper will perform, since only the libfuzzer engine can be "configured". This makes the engine configurable. At least the building works, i'm not sure about the rest. There are most likely things missing here. I'm also not sure how coverage/introspector builds should be handledm what should their engine be? Refs. #13346
1 parent c51d91d commit ef93cca

20 files changed

+91
-44
lines changed

infra/build/functions/build_project.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
GCB_EXPERIMENT_LOGS_BUCKET = 'oss-fuzz-gcb-experiment-logs'
4545

4646
DEFAULT_ARCHITECTURES = ['x86_64']
47-
DEFAULT_ENGINES = ['libfuzzer', 'afl', 'honggfuzz', 'centipede']
47+
DEFAULT_FUZZING_ENGINES = ['libfuzzer', 'afl', 'honggfuzz', 'centipede']
4848
DEFAULT_SANITIZERS = ['address', 'undefined']
4949

5050
LATEST_VERSION_FILENAME = 'latest.version'
@@ -218,7 +218,7 @@ def set_yaml_defaults(project_yaml):
218218
project_yaml.setdefault('disabled', False)
219219
project_yaml.setdefault('architectures', DEFAULT_ARCHITECTURES)
220220
project_yaml.setdefault('sanitizers', DEFAULT_SANITIZERS)
221-
project_yaml.setdefault('fuzzing_engines', DEFAULT_ENGINES)
221+
project_yaml.setdefault('fuzzing_engines', DEFAULT_FUZZING_ENGINES)
222222
project_yaml.setdefault('run_tests', True)
223223
project_yaml.setdefault('coverage_extra_args', '')
224224
project_yaml.setdefault('labels', {})

infra/ci/build.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
CANARY_PROJECT = 'skcms'
3434

3535
DEFAULT_ARCHITECTURES = ['x86_64']
36-
DEFAULT_ENGINES = ['afl', 'honggfuzz', 'libfuzzer', 'centipede']
36+
DEFAULT_FUZZING_ENGINES = ['afl', 'honggfuzz', 'libfuzzer', 'centipede']
3737
DEFAULT_SANITIZERS = ['address', 'undefined']
3838

3939

@@ -105,7 +105,7 @@ def should_build_coverage(project_yaml):
105105
contents."""
106106
# Enable coverage builds on projects that use engines. Those that don't use
107107
# engines shouldn't get coverage builds.
108-
engines = project_yaml.get('fuzzing_engines', DEFAULT_ENGINES)
108+
engines = project_yaml.get('fuzzing_engines', DEFAULT_FUZZING_ENGINES)
109109
engineless = 'none' in engines
110110
if engineless:
111111
assert_message = ('Forbidden to specify multiple engines for '
@@ -153,7 +153,7 @@ def is_enabled(env_var, yaml_name, defaults):
153153
return os.getenv(env_var) in flatten_options(
154154
project_yaml.get(yaml_name, defaults))
155155

156-
return (is_enabled('ENGINE', 'fuzzing_engines', DEFAULT_ENGINES) and
156+
return (is_enabled('ENGINE', 'fuzzing_engines', DEFAULT_FUZZING_ENGINES) and
157157
is_enabled('SANITIZER', 'sanitizers', DEFAULT_SANITIZERS) and
158158
is_enabled('ARCHITECTURE', 'architectures', DEFAULT_ARCHITECTURES))
159159

infra/cifuzz/actions/build_fuzzers/action.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ inputs:
1818
sanitizer:
1919
description: 'The sanitizer to build the fuzzers with.'
2020
default: 'address'
21+
fuzzing_engine:
22+
description: 'The fuzzing engine to build the fuzzers with.'
23+
default: 'libfuzzer'
2124
architecture:
2225
description: 'The architecture used to build the fuzzers.'
2326
default: 'x86_64'
@@ -45,6 +48,7 @@ runs:
4548
DRY_RUN: ${{ inputs.dry-run}}
4649
ALLOWED_BROKEN_TARGETS_PERCENTAGE: ${{ inputs.allowed-broken-targets-percentage}}
4750
SANITIZER: ${{ inputs.sanitizer }}
51+
FUZZING_ENGINE: ${{ inputs.fuzzing_engine }}
4852
ARCHITECTURE: ${{ inputs.architecture }}
4953
PROJECT_SRC_PATH: ${{ inputs.project-src-path }}
5054
LOW_DISK_SPACE: 'True'

infra/cifuzz/actions/run_fuzzers/action.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ inputs:
1919
sanitizer:
2020
description: 'The sanitizer to run the fuzzers with.'
2121
default: 'address'
22+
fuzzing_engine:
23+
description: 'The fuzzing engine to run the fuzzers with.'
24+
default: 'libfuzzer'
2225
mode:
2326
description: |
2427
The mode to run the fuzzers with ("code-change", "batch", "coverage", or "prune").
@@ -69,6 +72,7 @@ runs:
6972
FUZZ_SECONDS: ${{ inputs.fuzz-seconds }}
7073
DRY_RUN: ${{ inputs.dry-run}}
7174
SANITIZER: ${{ inputs.sanitizer }}
75+
FUZZING_ENGINE: ${{ inputs.fuzzing_engine }}
7276
MODE: ${{ inputs.mode }}
7377
GITHUB_TOKEN: ${{ inputs.github-token }}
7478
LOW_DISK_SPACE: 'True'

infra/cifuzz/base_runner_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ def get_env(config, workspace):
2323
vars set to values needed to run a fuzzer."""
2424
env = os.environ.copy()
2525
env['SANITIZER'] = config.sanitizer
26+
env['FUZZING_ENGINE'] = config.fuzzing_engine
2627
env['FUZZING_LANGUAGE'] = config.language
2728
env['OUT'] = workspace.out
2829
env['CIFUZZ'] = 'True'
29-
env['FUZZING_ENGINE'] = config_utils.DEFAULT_ENGINE
3030
env['ARCHITECTURE'] = config.architecture
3131
# Do this so we don't fail in tests.
3232
env['FUZZER_ARGS'] = '-rss_limit_mb=2560 -timeout=25'

infra/cifuzz/build_fuzzers.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,9 @@ def build_fuzzers(self):
8181
"""Moves the source code we want to fuzz into the project builder and builds
8282
the fuzzers from that source code. Returns True on success."""
8383
docker_args, docker_container = docker.get_base_docker_run_args(
84-
self.workspace, self.config.sanitizer, self.config.language,
85-
self.config.architecture, self.config.docker_in_docker)
84+
self.workspace, self.config.sanitizer, self.config.fuzzing_engine,
85+
self.config.language, self.config.architecture,
86+
self.config.docker_in_docker)
8687
if not docker_container:
8788
docker_args.extend(
8889
_get_docker_build_fuzzers_args_not_container(self.host_repo_path))
@@ -101,7 +102,8 @@ def build_fuzzers(self):
101102
'-c',
102103
build_command,
103104
])
104-
logging.info('Building with %s sanitizer.', self.config.sanitizer)
105+
logging.info('Building with %s sanitizer, %s fuzzing engine.',
106+
self.config.sanitizer, self.config.fuzzing_engine)
105107

106108
# TODO(metzman): Stop using helper.docker_run so we can get rid of
107109
# docker.get_base_docker_run_args and merge its contents into

infra/cifuzz/build_fuzzers_test.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ class InternalGithubBuildTest(unittest.TestCase):
119119
"""Tests for building OSS-Fuzz projects on GitHub actions."""
120120
PROJECT_REPO_NAME = 'myproject'
121121
SANITIZER = 'address'
122+
ENGING = 'libfuzzer'
122123
GIT_SHA = 'fake'
123124
PR_REF = 'fake'
124125

@@ -129,6 +130,7 @@ def _create_builder(self, tmp_dir, oss_fuzz_project_name='myproject'):
129130
project_repo_name=self.PROJECT_REPO_NAME,
130131
workspace=tmp_dir,
131132
sanitizer=self.SANITIZER,
133+
engine=self.FUZZING_ENGINE,
132134
git_sha=self.GIT_SHA,
133135
pr_ref=self.PR_REF,
134136
cfl_platform='github')
@@ -315,6 +317,7 @@ class CheckFuzzerBuildTest(unittest.TestCase):
315317
"""Tests the check_fuzzer_build function in the cifuzz module."""
316318

317319
SANITIZER = 'address'
320+
FUZZING_ENGINE = 'libfuzzer'
318321
LANGUAGE = 'c++'
319322

320323
def setUp(self):
@@ -323,6 +326,7 @@ def setUp(self):
323326
self.config = test_helpers.create_build_config(
324327
oss_fuzz_project_name=EXAMPLE_PROJECT,
325328
sanitizer=self.SANITIZER,
329+
engine=self.FUZZING_ENGINE,
326330
language=self.LANGUAGE,
327331
workspace=workspace_path,
328332
pr_ref='refs/pull/1757/merge')

infra/cifuzz/clusterfuzz_deployment.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ def download_corpus(self, target_name, corpus_dir):
153153
return corpus_dir
154154

155155
def _get_build_name(self, name):
156-
return f'{self.config.sanitizer}-{name}'
156+
return f'{self.config.sanitizer}-{self.config.fuzzing_engine}-{name}'
157157

158158
def _get_corpus_name(self, target_name): # pylint: disable=no-self-use
159159
"""Returns the name of the corpus artifact."""

infra/cifuzz/config_utils.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,12 @@
2727
import platform_config
2828
import constants
2929

30-
SANITIZERS = ['address', 'memory', 'undefined', 'coverage']
30+
SANITIZERS = ['address', 'memory', 'undefined', 'coverage', 'introspector']
31+
32+
FUZZING_ENGINES = ['libfuzzer', 'afl', 'honggfuzz', 'none']
3133

3234
# TODO(metzman): Set these on config objects so there's one source of truth.
33-
DEFAULT_ENGINE = 'libfuzzer'
35+
DEFAULT_FUZZING_ENGINE = 'libfuzzer'
3436

3537
# This module deals a lot with env variables. Many of these will be set by users
3638
# and others beyond CIFuzz's control. Thus, you should be careful about using
@@ -44,6 +46,10 @@ def _get_sanitizer():
4446
return os.getenv('SANITIZER', constants.DEFAULT_SANITIZER).lower()
4547

4648

49+
def _get_engine():
50+
return os.getenv('FUZZING_ENGINE', constants.DEFAULT_FUZZING_ENGINE).lower()
51+
52+
4753
def _get_architecture():
4854
return os.getenv('ARCHITECTURE', constants.DEFAULT_ARCHITECTURE).lower()
4955

@@ -115,6 +121,7 @@ def __init__(self):
115121

116122
self.dry_run = _is_dry_run() # Check if failures should not be reported.
117123
self.sanitizer = _get_sanitizer()
124+
self.fuzzing_engine = _get_engine()
118125
self.architecture = _get_architecture()
119126
self.language = _get_language()
120127
self.low_disk_space = environment.get_bool('LOW_DISK_SPACE', False)
@@ -152,6 +159,11 @@ def validate(self):
152159
self.sanitizer, SANITIZERS)
153160
return False
154161

162+
if self.fuzzing_engine not in FUZZING_ENGINES:
163+
logging.error('Invalid FUZZING_ENGINE: %s. Must be one of: %s.',
164+
self.fuzzing_engine, FUZZING_ENGINES)
165+
return False
166+
155167
if self.architecture not in constants.ARCHITECTURES:
156168
logging.error('Invalid ARCHITECTURE: %s. Must be one of: %s.',
157169
self.architecture, constants.ARCHITECTURES)

infra/cifuzz/continuous_integration.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,8 +239,9 @@ def _copy_repo_from_image(self, image_repo_path):
239239
host_repo_path = os.path.join(self._repo_dir, repo_name)
240240
bash_command = f'cp -r {image_repo_path} {host_repo_path}'
241241
docker_args, _ = docker.get_base_docker_run_args(
242-
self.workspace, self.config.sanitizer, self.config.language,
243-
self.config.architecture, self.config.docker_in_docker)
242+
self.workspace, self.config.sanitizer, self.config.fuzzing_engine,
243+
self.config.language, self.config.architecture,
244+
self.config.docker_in_docker)
244245
docker_args.extend([
245246
docker.get_project_image_name(self.config.oss_fuzz_project_name),
246247
'/bin/bash', '-c', bash_command

infra/cifuzz/docker.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@
2828
PROJECT_TAG_PREFIX = 'gcr.io/oss-fuzz/'
2929

3030
# Default fuzz configuration.
31-
_DEFAULT_DOCKER_RUN_ARGS = [
32-
'-e', 'FUZZING_ENGINE=' + constants.DEFAULT_ENGINE, '-e', 'CIFUZZ=True'
33-
]
31+
_DEFAULT_DOCKER_RUN_ARGS = ['-e', 'CIFUZZ=True']
3432

3533
UNIQUE_ID_SUFFIX = '-' + uuid.uuid4().hex
3634

@@ -75,6 +73,7 @@ def delete_images(images):
7573

7674
def get_base_docker_run_args(workspace,
7775
sanitizer=constants.DEFAULT_SANITIZER,
76+
engine=constants.DEFAULT_FUZZING_ENGINE,
7877
language=constants.DEFAULT_LANGUAGE,
7978
architecture=constants.DEFAULT_ARCHITECTURE,
8079
docker_in_docker=False):
@@ -83,6 +82,7 @@ def get_base_docker_run_args(workspace,
8382
docker_args = _DEFAULT_DOCKER_RUN_ARGS.copy()
8483
env_mapping = {
8584
'SANITIZER': sanitizer,
85+
'FUZZING_ENGINE': engine,
8686
'ARCHITECTURE': architecture,
8787
'FUZZING_LANGUAGE': language,
8888
'OUT': workspace.out
@@ -102,6 +102,7 @@ def get_base_docker_run_args(workspace,
102102

103103
def get_base_docker_run_command(workspace,
104104
sanitizer=constants.DEFAULT_SANITIZER,
105+
engine=constants.DEFAULT_FUZZING_ENGINE,
105106
language=constants.DEFAULT_LANGUAGE,
106107
architecture=constants.DEFAULT_ARCHITECTURE,
107108
docker_in_docker=False):
@@ -110,6 +111,7 @@ def get_base_docker_run_command(workspace,
110111
docker_args, docker_container = get_base_docker_run_args(
111112
workspace,
112113
sanitizer,
114+
engine,
113115
language,
114116
architecture,
115117
docker_in_docker=docker_in_docker)

infra/cifuzz/docker_test.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
config.workspace = '/workspace'
2626
WORKSPACE = workspace_utils.Workspace(config)
2727
SANITIZER = 'example-sanitizer'
28+
FUZZING_ENGINE = 'example-fuzzing-engine'
2829
LANGUAGE = 'example-language'
2930

3031

@@ -62,7 +63,7 @@ def test_get_base_docker_run_args_container(self, _):
6263
"""Tests that get_base_docker_run_args works as intended when inside a
6364
container."""
6465
docker_args, docker_container = docker.get_base_docker_run_args(
65-
WORKSPACE, SANITIZER, LANGUAGE)
66+
WORKSPACE, SANITIZER, FUZZING_ENGINE, LANGUAGE)
6667
self.assertEqual(docker_container, CONTAINER_NAME)
6768
expected_docker_args = []
6869
expected_docker_args = [
@@ -73,6 +74,8 @@ def test_get_base_docker_run_args_container(self, _):
7374
'-e',
7475
f'SANITIZER={SANITIZER}',
7576
'-e',
77+
f'FUZZING_ENGINE={FUZZING_ENGINE}',
78+
'-e',
7679
'ARCHITECTURE=x86_64',
7780
'-e',
7881
f'FUZZING_LANGUAGE={LANGUAGE}',
@@ -88,12 +91,13 @@ def test_get_base_docker_run_args_no_container(self, _):
8891
"""Tests that get_base_docker_run_args works as intended when not inside a
8992
container."""
9093
docker_args, docker_container = docker.get_base_docker_run_args(
91-
WORKSPACE, SANITIZER, LANGUAGE)
94+
WORKSPACE, SANITIZER, FUZZING_ENGINE, LANGUAGE)
9295
self.assertEqual(docker_container, None)
9396
expected_docker_args = [
9497
'-e', 'FUZZING_ENGINE=libfuzzer', '-e', 'CIFUZZ=True', '-e',
95-
f'SANITIZER={SANITIZER}', '-e', 'ARCHITECTURE=x86_64', '-e',
96-
f'FUZZING_LANGUAGE={LANGUAGE}', '-e', f'OUT={WORKSPACE.out}', '-v',
98+
f'SANITIZER={SANITIZER}', '-e', f'FUZZING_ENGINE={FUZZING_ENGINE}',
99+
'-e', 'ARCHITECTURE=x86_64', '-e', f'FUZZING_LANGUAGE={LANGUAGE}', '-e',
100+
f'OUT={WORKSPACE.out}', '-v',
97101
f'{WORKSPACE.workspace}:{WORKSPACE.workspace}'
98102
]
99103
self.assertEqual(docker_args, expected_docker_args)

infra/cifuzz/external-actions/build_fuzzers/action.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ inputs:
1515
sanitizer:
1616
description: 'The sanitizer to build the fuzzers with.'
1717
default: 'address'
18+
fuzzing_engine:
19+
description: 'The fuzzing engine to build the fuzzers with.'
20+
default: 'libfuzzer'
1821
project-src-path:
1922
description: "The path to the project's source code checkout."
2023
required: false
@@ -64,6 +67,7 @@ runs:
6467
DRY_RUN: ${{ inputs.dry-run}}
6568
ALLOWED_BROKEN_TARGETS_PERCENTAGE: ${{ inputs.allowed-broken-targets-percentage}}
6669
SANITIZER: ${{ inputs.sanitizer }}
70+
FUZZING_ENGINE: ${{ inputs.fuzzing_engine }}
6771
PROJECT_SRC_PATH: ${{ inputs.project-src-path }}
6872
GITHUB_TOKEN: ${{ inputs.github-token }}
6973
LOW_DISK_SPACE: 'True'

infra/cifuzz/external-actions/run_fuzzers/action.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ inputs:
1616
sanitizer:
1717
description: 'The sanitizer to run the fuzzers with.'
1818
default: 'address'
19+
fuzzing_engine:
20+
description: 'The fuzzing engine to run the fuzzers with.'
21+
default: 'libfuzzer'
1922
mode:
2023
description: |
2124
The mode to run the fuzzers with ("code-change", "batch", "coverage", or "prune").
@@ -81,6 +84,7 @@ runs:
8184
FUZZ_SECONDS: ${{ inputs.fuzz-seconds }}
8285
DRY_RUN: ${{ inputs.dry-run}}
8386
SANITIZER: ${{ inputs.sanitizer }}
87+
FUZZING_ENGINE: ${{ inputs.fuzzing_engine }}
8488
MODE: ${{ inputs.mode }}
8589
GITHUB_TOKEN: ${{ inputs.github-token }}
8690
LOW_DISK_SPACE: 'True'

0 commit comments

Comments
 (0)