diff --git a/grizzly/args.py b/grizzly/args.py index 0f6c6a84..a28badb9 100644 --- a/grizzly/args.py +++ b/grizzly/args.py @@ -8,6 +8,7 @@ from pathlib import Path from platform import system +from .common.fuzzmanager import FM_CONFIG, ProgramConfiguration from .common.plugins import scan as scan_plugins from .common.plugins import scan_target_assets from .common.utils import DEFAULT_TIME_LIMIT, TIMEOUT_DELAY, __version__ @@ -265,6 +266,18 @@ def sanity_check(self, args): if not args.binary.is_file(): self.parser.error(f"file not found: '{args.binary!s}'") + # fuzzmanager reporter related checks + if args.fuzzmanager: + if not FM_CONFIG.is_file(): + self.parser.error(f"--fuzzmanager: missing '{FM_CONFIG}'") + bin_cfg = Path(f"{args.binary}.fuzzmanagerconf") + if not bin_cfg.is_file(): + self.parser.error(f"--fuzzmanager: missing '{bin_cfg}'") + try: + ProgramConfiguration.fromBinary(str(args.binary)) + except RuntimeError as exc: + self.parser.error(f"--fuzzmanager, {exc}") + if args.launch_attempts < 1: self.parser.error("--launch-attempts must be >= 1") diff --git a/grizzly/common/fuzzmanager.py b/grizzly/common/fuzzmanager.py index 0f91f046..02284c98 100644 --- a/grizzly/common/fuzzmanager.py +++ b/grizzly/common/fuzzmanager.py @@ -17,6 +17,7 @@ from .reporter import Quality from .utils import grz_tmp +FM_CONFIG = Path.home() / ".fuzzmanagerconf" LOG = getLogger(__name__) diff --git a/grizzly/common/reporter.py b/grizzly/common/reporter.py index bdf42284..960b6588 100644 --- a/grizzly/common/reporter.py +++ b/grizzly/common/reporter.py @@ -11,10 +11,8 @@ from tempfile import TemporaryDirectory from zipfile import ZIP_DEFLATED, ZipFile -# import FuzzManager utilities from Collector.Collector import Collector from fasteners.process_lock import InterProcessLock -from FTB.ProgramConfiguration import ProgramConfiguration from psutil import disk_usage from .report import Report @@ -166,8 +164,6 @@ def _post_submit(self): class FuzzManagerReporter(Reporter): - FM_CONFIG = Path.home() / ".fuzzmanagerconf" - __slots__ = ("_extra_metadata", "quality", "tool") def __init__(self, tool): @@ -182,22 +178,6 @@ def __init__(self, tool): def _post_submit(self): self._extra_metadata.clear() - @staticmethod - def sanity_check(bin_file): - """Perform FuzzManager sanity check. - - Args: - bin_file (Path): Binary file being tested. - - Returns: - None - """ - if not FuzzManagerReporter.FM_CONFIG.is_file(): - raise OSError(f"Missing: {FuzzManagerReporter.FM_CONFIG}") - if not Path(f"{bin_file}.fuzzmanagerconf").is_file(): - raise OSError(f"Missing: {bin_file}.fuzzmanagerconf") - ProgramConfiguration.fromBinary(str(bin_file)) - def add_extra_metadata(self, key, value): """Add extra metadata to be reported with any CrashEntrys reported. diff --git a/grizzly/common/test_reporter.py b/grizzly/common/test_reporter.py index 06041785..9fbbcd14 100644 --- a/grizzly/common/test_reporter.py +++ b/grizzly/common/test_reporter.py @@ -5,7 +5,6 @@ # pylint: disable=protected-access from pathlib import Path -from FTB.ProgramConfiguration import ProgramConfiguration from pytest import mark, raises from .report import Report @@ -133,28 +132,6 @@ def test_filesystem_reporter_04(mocker, tmp_path): assert any((tmp_path / "dst").glob("test_prefix_logs")) -def test_fuzzmanager_reporter_01(mocker, tmp_path): - """test FuzzManagerReporter.sanity_check()""" - fake_reporter = mocker.patch("grizzly.common.reporter.ProgramConfiguration") - fake_reporter.fromBinary.return_value = mocker.Mock(spec_set=ProgramConfiguration) - # missing global FM config file - FuzzManagerReporter.FM_CONFIG = tmp_path / "no_file" - with raises(IOError, match="no_file"): - FuzzManagerReporter.sanity_check("fake") - # missing binary FM config file - fake_fmc = tmp_path / ".fuzzmanagerconf" - fake_fmc.touch() - fake_bin = tmp_path / "bin" - fake_bin.touch() - FuzzManagerReporter.FM_CONFIG = fake_fmc - with raises(IOError, match="bin.fuzzmanagerconf"): - FuzzManagerReporter.sanity_check(str(fake_bin)) - # success - (tmp_path / "bin.fuzzmanagerconf").touch() - FuzzManagerReporter.sanity_check(str(fake_bin)) - assert fake_reporter.fromBinary.call_count == 1 - - @mark.parametrize( "tests, frequent, force, sig_cache", [ @@ -170,7 +147,7 @@ def test_fuzzmanager_reporter_01(mocker, tmp_path): (False, False, False, False), ], ) -def test_fuzzmanager_reporter_02(mocker, tmp_path, tests, frequent, force, sig_cache): +def test_fuzzmanager_reporter_01(mocker, tmp_path, tests, frequent, force, sig_cache): """test FuzzManagerReporter.submit()""" mocker.patch("grizzly.common.reporter.Path.cwd", return_value=tmp_path) mocker.patch("grizzly.common.reporter.getenv", autospec=True, return_value="0") diff --git a/grizzly/main.py b/grizzly/main.py index 8595b5aa..26dcad26 100644 --- a/grizzly/main.py +++ b/grizzly/main.py @@ -33,8 +33,6 @@ def main(args): configure_logging(args.log_level) LOG.info("Starting Grizzly (%d)", getpid()) - if args.fuzzmanager: - FuzzManagerReporter.sanity_check(args.binary) if args.headless: LOG.info("Running browser headless (%s)", args.headless) diff --git a/grizzly/reduce/conftest.py b/grizzly/reduce/conftest.py index 270ad850..00011b91 100644 --- a/grizzly/reduce/conftest.py +++ b/grizzly/reduce/conftest.py @@ -8,18 +8,6 @@ import pytest -@pytest.fixture -def tmp_path_fm_config(tmp_path, mocker): - """Ensure fm config is always read from tmp_path so ~/.fuzzmanagerconf - can't be used by accident. - """ - mocker.patch( - "grizzly.reduce.core.FuzzManagerReporter.FM_CONFIG", - new=str(tmp_path / ".fuzzmanagerconf"), - ) - (tmp_path / ".fuzzmanagerconf").touch() - - @pytest.fixture def reporter_sequential_strftime(mocker): """Make `strftime` in `FilesystemReporter` return sequential values. diff --git a/grizzly/reduce/core.py b/grizzly/reduce/core.py index c5e7b3ad..635b0c59 100644 --- a/grizzly/reduce/core.py +++ b/grizzly/reduce/core.py @@ -766,8 +766,6 @@ def main(cls, args): # pylint: disable=too-many-return-statements configure_logging(args.log_level) setlocale(LC_ALL, "") - if args.fuzzmanager: - FuzzManagerReporter.sanity_check(args.binary) LOG.info("Starting Grizzly Reduce") diff --git a/grizzly/reduce/test_main.py b/grizzly/reduce/test_main.py index 8e1958fb..28d525c6 100644 --- a/grizzly/reduce/test_main.py +++ b/grizzly/reduce/test_main.py @@ -13,10 +13,7 @@ from .args import ReduceArgs, ReduceFuzzManagerIDArgs, ReduceFuzzManagerIDQualityArgs from .exceptions import GrizzlyReduceBaseException -pytestmark = mark.usefixtures( - "tmp_path_fm_config", - "tmp_path_status_db_reduce", -) +pytestmark = mark.usefixtures("tmp_path_status_db_reduce") def test_args_01(capsys, tmp_path, mocker): diff --git a/grizzly/reduce/test_main_fm.py b/grizzly/reduce/test_main_fm.py index 6b175e00..2eeec561 100644 --- a/grizzly/reduce/test_main_fm.py +++ b/grizzly/reduce/test_main_fm.py @@ -8,10 +8,7 @@ from ..common.utils import Exit from .crash import main as crash_main -pytestmark = mark.usefixtures( - "tmp_path_fm_config", - "tmp_path_status_db_reduce", -) +pytestmark = mark.usefixtures("tmp_path_status_db_reduce") @mark.parametrize( diff --git a/grizzly/reduce/test_reduce.py b/grizzly/reduce/test_reduce.py index ae1bccd7..2638e011 100644 --- a/grizzly/reduce/test_reduce.py +++ b/grizzly/reduce/test_reduce.py @@ -25,7 +25,6 @@ LOG = getLogger(__name__) pytestmark = mark.usefixtures( "reporter_sequential_strftime", - "tmp_path_fm_config", "tmp_path_status_db_reduce", ) diff --git a/grizzly/reduce/test_strategies.py b/grizzly/reduce/test_strategies.py index df7e1f2b..dfefc59c 100644 --- a/grizzly/reduce/test_strategies.py +++ b/grizzly/reduce/test_strategies.py @@ -21,7 +21,6 @@ LOG = getLogger(__name__) pytestmark = mark.usefixtures( "reporter_sequential_strftime", - "tmp_path_fm_config", "tmp_path_status_db_reduce", ) diff --git a/grizzly/replay/replay.py b/grizzly/replay/replay.py index d218e191..2ea8f5ec 100644 --- a/grizzly/replay/replay.py +++ b/grizzly/replay/replay.py @@ -579,9 +579,6 @@ def run( @classmethod def main(cls, args): configure_logging(args.log_level) - if args.fuzzmanager: - FuzzManagerReporter.sanity_check(args.binary) - LOG.info("Starting Grizzly Replay") if args.headless: diff --git a/grizzly/test_args.py b/grizzly/test_args.py index d593970f..2585439a 100644 --- a/grizzly/test_args.py +++ b/grizzly/test_args.py @@ -123,6 +123,10 @@ def test_common_args_02(capsys, mocker, args, msg, idx): ) def test_common_args_03(capsys, mocker, tmp_path, args, msg, targets): """test CommonArgs.parse_args()""" + fm_config = tmp_path / ".fuzzmanagerconf" + fm_config.touch() + mocker.patch("grizzly.args.FM_CONFIG", fm_config) + mocker.patch("grizzly.args.ProgramConfiguration", autospec=True) mocker.patch("grizzly.args.scan_plugins", autospec=True, return_value=targets) mocker.patch( "grizzly.args.scan_target_assets", @@ -132,6 +136,7 @@ def test_common_args_03(capsys, mocker, tmp_path, args, msg, targets): mocker.patch("grizzly.args.system", autospec=True, return_value="foo") fake_bin = tmp_path / "fake.bin" fake_bin.touch() + fake_bin.with_suffix(fake_bin.suffix + ".fuzzmanagerconf").touch() with raises(SystemExit): CommonArgs().parse_args(argv=[str(fake_bin)] + args) assert msg in capsys.readouterr()[-1] @@ -160,6 +165,32 @@ def test_common_args_05(mocker): assert CommonArgs.is_headless() +def test_common_args_06(capsys, mocker, tmp_path): + """test CommonArgs fuzzmanager checks""" + fake_bin = tmp_path / "bin.exe" + fake_bin.touch() + bin_config = tmp_path / "bin.exe.fuzzmanagerconf" + fm_config = tmp_path / ".fuzzmanagerconf" + mocker.patch("grizzly.args.FM_CONFIG", fm_config) + + # missing system .fuzzmanagerconf + with raises(SystemExit): + CommonArgs().parse_args(argv=[str(fake_bin), "--fuzzmanager"]) + assert f"--fuzzmanager: missing '{fm_config}'" in capsys.readouterr()[-1] + + fm_config.touch() + # missing binary.fuzzmanagerconf + with raises(SystemExit): + CommonArgs().parse_args(argv=[str(fake_bin), "--fuzzmanager"]) + assert f"--fuzzmanager: missing '{bin_config}'" in capsys.readouterr()[-1] + + bin_config.touch() + # bad binary.fuzzmanagerconf + with raises(SystemExit): + CommonArgs().parse_args(argv=[str(fake_bin), "--fuzzmanager"]) + assert '"product" in binary configuration file' in capsys.readouterr()[-1] + + @mark.parametrize( "extra_args, results", [ diff --git a/grizzly/test_main.py b/grizzly/test_main.py index e6de864d..d6b0cc4d 100644 --- a/grizzly/test_main.py +++ b/grizzly/test_main.py @@ -35,8 +35,6 @@ (0, ["--ignore", "timeout"]), # headless (0, ["--headless"]), - # FuzzManager reporter - (0, ["--fuzzmanager"]), # verbose mode (0, ["--verbose"]), ],