Skip to content

Commit 77ea427

Browse files
authored
centipede: create workdir in prepare instead of the constructor (#4674)
It turns out that the same class can be used for different fuzzing rounds, and the parent directory of the temp dir is being cleared in between each round. For that reason, we need to re-create a workdir in `prepare`.
1 parent ca14f3a commit 77ea427

File tree

1 file changed

+11
-8
lines changed
  • src/clusterfuzz/_internal/bot/fuzzers/centipede

1 file changed

+11
-8
lines changed

src/clusterfuzz/_internal/bot/fuzzers/centipede/engine.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,6 @@ def _parse_centipede_logs(log_lines: List[str]) -> Dict[str, int]:
147147
class Engine(engine.Engine):
148148
"""Centipede engine implementation."""
149149

150-
def __init__(self):
151-
super().__init__()
152-
self.workdir = self._create_temp_dir('workdir')
153-
154150
@property
155151
def name(self):
156152
return 'centipede'
@@ -202,7 +198,8 @@ def prepare(self, corpus_dir, target_path, build_dir):
202198
# 1. Centipede-readable corpus file;
203199
# 2. Centipede-readable feature file;
204200
# 3. Crash reproducing inputs.
205-
arguments[constants.WORKDIR_FLAGNAME] = str(self.workdir)
201+
workdir = self._create_temp_dir('workdir')
202+
arguments[constants.WORKDIR_FLAGNAME] = str(workdir)
206203

207204
# Directory corpus_dir saves the corpus files required by ClusterFuzz.
208205
arguments[constants.CORPUS_DIR_FLAGNAME] = corpus_dir
@@ -301,7 +298,12 @@ def fuzz(self, target_path, options, reproducers_dir, max_time): # pylint: disa
301298
int(fuzz_result.time_executed)))
302299

303300
stats_filename = f'fuzzing-stats-{os.path.basename(target_path)}.000000.csv'
304-
stats_file = os.path.join(self.workdir, stats_filename)
301+
args = fuzzer_options.FuzzerArguments.from_list(options.arguments)
302+
assert args is not None
303+
assert constants.WORKDIR_FLAGNAME in args
304+
305+
workdir = args[constants.WORKDIR_FLAGNAME]
306+
stats_file = os.path.join(workdir, stats_filename)
305307
stats = _parse_centipede_stats(stats_file)
306308
if not stats:
307309
stats = {}
@@ -505,9 +507,10 @@ def minimize_testcase(self, target_path, arguments, input_path, output_path,
505507
TimeoutError: If the testcase minimization exceeds max_time.
506508
"""
507509
runner = _get_runner(target_path)
510+
workdir = self._create_temp_dir('workdir')
508511
args = [
509512
f'--binary={target_path}',
510-
f'--workdir={self.workdir}',
513+
f'--workdir={workdir}',
511514
f'--minimize_crash={input_path}',
512515
f'--num_runs={constants.NUM_RUNS_PER_MINIMIZATION}',
513516
'--seed=1',
@@ -517,7 +520,7 @@ def minimize_testcase(self, target_path, arguments, input_path, output_path,
517520
logs.warning(
518521
'Testcase minimization timed out.', fuzzer_output=result.output)
519522
raise TimeoutError('Minimization timed out.')
520-
minimum_testcase = self._get_smallest_crasher(self.workdir)
523+
minimum_testcase = self._get_smallest_crasher(workdir)
521524
if minimum_testcase:
522525
shutil.copyfile(minimum_testcase, output_path)
523526
else:

0 commit comments

Comments
 (0)