Skip to content

Commit 613e1c6

Browse files
authored
Implement fuzzer weight setting. (#4392)
This allows manipulating the weight of individual FuzzerJob entries in the database. Complements the `fuzz-target set` command.
1 parent c46d537 commit 613e1c6

File tree

2 files changed

+64
-3
lines changed

2 files changed

+64
-3
lines changed

butler.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,25 @@ def _add_weights_fuzzer_subparser(weights_subparsers):
132132
aggregate_parser.add_argument(
133133
'-j', '--jobs', help='Which jobs to aggregate.', nargs='+')
134134

135+
set_parser = subparsers.add_parser(
136+
'set', help='Set the weight of a FuzzerJob entry.')
137+
set_parser.add_argument(
138+
'-f',
139+
'--fuzzer',
140+
help='The fuzzer field of the entry to modify.',
141+
required=True)
142+
set_parser.add_argument(
143+
'-j',
144+
'--job',
145+
help='The job field of the entry to modify.',
146+
required=True)
147+
set_parser.add_argument(
148+
'-w',
149+
'--weight',
150+
help='The new weight to set.',
151+
type=float,
152+
required=True)
153+
135154

136155
def _add_weights_batches_subparser(weights_subparsers):
137156
"""Adds a parser for the `weights fuzzer-batch` command."""

src/local/butler/weights.py

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@
3939

4040
def _iter_weights(
4141
fuzzer_jobs: Sequence[data_types.FuzzerJob]) -> Sequence[float]:
42-
for fj in fuzzer_jobs:
43-
yield fj.actual_weight
42+
for fuzzer_job in fuzzer_jobs:
43+
yield fuzzer_job.actual_weight
4444

4545

4646
def _sum_weights(fuzzer_jobs: Sequence[data_types.FuzzerJob]) -> float:
@@ -123,7 +123,8 @@ def _display_fuzzer_jobs(fuzzer_jobs: Sequence[data_types.FuzzerJob],
123123
printer = _print_with_prefix(prefix)
124124

125125
fuzzer_jobs = list(fuzzer_jobs)
126-
fuzzer_jobs.sort(key=lambda fj: fj.actual_weight, reverse=True)
126+
fuzzer_jobs.sort(
127+
key=lambda fuzzer_job: fuzzer_job.actual_weight, reverse=True)
127128

128129
total_weight = _sum_weights(fuzzer_jobs)
129130

@@ -316,6 +317,45 @@ def _aggregate_fuzzer_jobs(
316317
_print_stats(others, total_weight)
317318

318319

320+
def _set_fuzzer_job_weight(
321+
fuzzer: str,
322+
job: str,
323+
weight: float,
324+
) -> None:
325+
"""Sets the matching FuzzerJob's weight to the given value."""
326+
fuzzer_jobs = list(
327+
data_types.FuzzerJob.query(data_types.FuzzerJob.fuzzer == fuzzer,
328+
data_types.FuzzerJob.job == job))
329+
330+
if not fuzzer_jobs:
331+
print('No matching FuzzerJob entries found for ' +
332+
f'fuzzer {fuzzer} and job {job}')
333+
return
334+
335+
if len(fuzzer_jobs) > 1:
336+
print('Bailing out! Multiple FuzzerJob entries found for ' +
337+
f'fuzzer {fuzzer} and job {job}: {fuzzer_jobs}')
338+
return
339+
340+
fuzzer_job = fuzzer_jobs[0]
341+
342+
print(f'Fuzzer: {fuzzer_job.fuzzer}')
343+
print(f'Job: {fuzzer_job.job}')
344+
print(f'Platform: {fuzzer_job.platform}')
345+
print(f'Multiplier: {fuzzer_job.multiplier}')
346+
print(f'Old weight: {fuzzer_job.weight}')
347+
print(f'-> New weight: {weight}')
348+
349+
answer = input('Do you want to apply this mutation? [y,n] ')
350+
if answer.lower() != 'y':
351+
print('Not applying mutation.')
352+
return
353+
354+
fuzzer_job.weight = weight
355+
fuzzer_job.put()
356+
print('Mutation applied.')
357+
358+
319359
def _set_fuzz_target_job_weight(
320360
fuzz_target_name: str,
321361
job: str,
@@ -362,6 +402,8 @@ def _execute_fuzzer_command(args) -> None:
362402
raise TypeError(f'--format {repr(args.format)} unrecognized')
363403
elif cmd == 'aggregate':
364404
_aggregate_fuzzer_jobs(args.platform, fuzzers=args.fuzzers, jobs=args.jobs)
405+
elif cmd == 'set':
406+
_set_fuzzer_job_weight(args.fuzzer, args.job, args.weight)
365407
else:
366408
raise TypeError(f'weights fuzzer command {repr(cmd)} unrecognized')
367409

0 commit comments

Comments
 (0)