diff --git a/bin/deepstate/core/fuzz.py b/bin/deepstate/core/fuzz.py index fc0f85ac..edb9f36a 100644 --- a/bin/deepstate/core/fuzz.py +++ b/bin/deepstate/core/fuzz.py @@ -143,6 +143,7 @@ def __init__(self) -> None: self.blackbox: Optional[bool] = None self.fuzzer_args: List[Any] = [] self.fuzzer_out: bool = False + self.abort_on_fail: bool = False self.sync_cycle: int = 5 self.sync_out: bool = True @@ -226,6 +227,10 @@ def parse_args(cls) -> Optional[argparse.Namespace]: parser.add_argument( "--fuzzer_args", default=[], nargs='*', help="Flags to pass to the fuzzer. Format: `a arg1=val` -> `-a --arg val`.") + + parser.add_argument( + "--abort_on_fail", action="store_true", + help="Fuzzer exits immediately on discovery of failiing input") # Parallel / Ensemble Fuzzing @@ -704,6 +709,18 @@ def run(self, runner: Optional[str] = None, no_exec: bool = False, skip_argparse run_fuzzer = False wait_time = 0 L.info("Timeout") + + # abort on fail check + if self.abort_on_fail: + crash_path = os.path.join(self.output_test_dir, "the_fuzzer", "crashes") + path = Path(crash_path) + if os.path.exists(path): + if len(os.listdir(path)) > 0: + run_one_fuzzer_process = False + run_fuzzer = False + L.info("Crash discovered. Check directory for crashes") + return 1 + try: # sleep/communicate for `self.sync_cycle` time diff --git a/docs/fuzzing.md b/docs/fuzzing.md index 61749ec2..a9f2e4c7 100644 --- a/docs/fuzzing.md +++ b/docs/fuzzing.md @@ -114,6 +114,7 @@ Optional arguments: --min_log_level - how much to log (0=DEBUG, 6=CRITICAL) --blackbox - fuzz non-instrumented binary --dictionary - file with words that may enhance fuzzing (fuzzer dependent format) +--abort_on_fail - fuzzers exits on first discovered crash ``` Each fuzzer creates following files/directories under output directory: