diff options
author | jonathanmetzman <31354670+jonathanmetzman@users.noreply.github.com> | 2021-07-29 08:41:36 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-29 15:41:36 +0000 |
commit | 8eb04554765201beacdc2a3eb98f6b725d222b75 (patch) | |
tree | e01f572056f57ee661f6d034cdb4541394a2dde9 /infra | |
parent | 729a8fe695ed583801a639552cc9991dbe21284d (diff) | |
download | oss-fuzz-8eb04554765201beacdc2a3eb98f6b725d222b75.tar.gz |
[CIFuzz] Allow users to specify if unreproducible crashes are reported (#6138)
Diffstat (limited to 'infra')
-rw-r--r-- | infra/cifuzz/actions/run_fuzzers/action.yml | 5 | ||||
-rw-r--r-- | infra/cifuzz/config_utils.py | 3 | ||||
-rw-r--r-- | infra/cifuzz/external-actions/run_fuzzers/action.yml | 5 | ||||
-rw-r--r-- | infra/cifuzz/fuzz_target.py | 4 | ||||
-rw-r--r-- | infra/cifuzz/fuzz_target_test.py | 42 |
5 files changed, 34 insertions, 25 deletions
diff --git a/infra/cifuzz/actions/run_fuzzers/action.yml b/infra/cifuzz/actions/run_fuzzers/action.yml index e7eaa8cb7..6386ba87d 100644 --- a/infra/cifuzz/actions/run_fuzzers/action.yml +++ b/infra/cifuzz/actions/run_fuzzers/action.yml @@ -35,6 +35,10 @@ inputs: TODO(https://github.com/google/oss-fuzz/pull/5841#discussion_r639393361): Document locking this down. required: false + report-unreproducible-crashes: + description: 'If True, then unreproducible crashes will be reported by CIFuzz.' + required: false + default: false runs: using: 'docker' image: '../../../run_fuzzers.Dockerfile' @@ -48,3 +52,4 @@ runs: BUILD_INTEGRATION_PATH: ${{ inputs.build-integration-path }} GITHUB_TOKEN: ${{ inputs.github-token }} LOW_DISK_SPACE: 'True' + REPORT_UNREPRODUCIBLE_CRASHES: ${{ inputs.report-unreproducible-crashes }} diff --git a/infra/cifuzz/config_utils.py b/infra/cifuzz/config_utils.py index c5fad7cb2..d15726307 100644 --- a/infra/cifuzz/config_utils.py +++ b/infra/cifuzz/config_utils.py @@ -165,6 +165,9 @@ class RunFuzzersConfig(BaseConfig): ('Invalid RUN_FUZZERS_MODE %s not one of allowed choices: %s.' % (self.run_fuzzers_mode, self.RUN_FUZZERS_MODES))) + self.report_unreproducible_crashes = environment.get_bool( + 'REPORT_UNREPRODUCIBLE_CRASHES', False) + class BuildFuzzersConfig(BaseConfig): """Class containing constant configuration for building fuzzers in CIFuzz.""" diff --git a/infra/cifuzz/external-actions/run_fuzzers/action.yml b/infra/cifuzz/external-actions/run_fuzzers/action.yml index f1ef5da3a..d6cc34c01 100644 --- a/infra/cifuzz/external-actions/run_fuzzers/action.yml +++ b/infra/cifuzz/external-actions/run_fuzzers/action.yml @@ -48,6 +48,10 @@ inputs: description: | The branch of the git repo to use for storing coverage reports. required: false + report-unreproducible-crashes: + description: 'If True, then unreproducible crashes will be reported by CIFuzz.' + required: false + default: false runs: using: 'docker' image: '../../../run_fuzzers.Dockerfile' @@ -64,3 +68,4 @@ runs: GIT_STORE_REPO: ${{ inputs.storage-repo }} GIT_STORE_BRANCH: ${{ inputs.storage-repo-branch }} GIT_STORE_BRANCH_COVERAGE: ${{ inputs.storage-repo-branch-coverage }} + REPORT_UNREPRODUCIBLE_CRASHES: ${{ inputs.report-unreproducible-crashes }} diff --git a/infra/cifuzz/fuzz_target.py b/infra/cifuzz/fuzz_target.py index 4f087ae48..19dec4022 100644 --- a/infra/cifuzz/fuzz_target.py +++ b/infra/cifuzz/fuzz_target.py @@ -243,10 +243,8 @@ class FuzzTarget: # pylint: disable=too-many-instance-attributes raise error if not reproducible_on_code_change: - # TODO(metzman): Allow users to specify if unreproducible crashes should - # be reported. logging.info('Crash is not reproducible.') - return False + return self.config.report_unreproducible_crashes logging.info('Crash is reproducible.') return self.is_crash_novel(testcase) diff --git a/infra/cifuzz/fuzz_target_test.py b/infra/cifuzz/fuzz_target_test.py index 3fdbfff55..acc61bbb8 100644 --- a/infra/cifuzz/fuzz_target_test.py +++ b/infra/cifuzz/fuzz_target_test.py @@ -75,10 +75,10 @@ class IsReproducibleTest(fake_filesystem_unittest.TestCase): self.fuzz_target_path = os.path.join(self.workspace.out, self.fuzz_target_name) self.testcase_path = '/testcase' - self.test_target = fuzz_target.FuzzTarget(self.fuzz_target_path, - fuzz_target.REPRODUCE_ATTEMPTS, - self.workspace, deployment, - deployment.config) + self.target = fuzz_target.FuzzTarget(self.fuzz_target_path, + fuzz_target.REPRODUCE_ATTEMPTS, + self.workspace, deployment, + deployment.config) def test_reproducible(self, _): """Tests that is_reproducible returns True if crash is detected and that @@ -86,13 +86,13 @@ class IsReproducibleTest(fake_filesystem_unittest.TestCase): self._set_up_fakefs() all_repro = [EXECUTE_FAILURE_RETVAL] * fuzz_target.REPRODUCE_ATTEMPTS with mock.patch('utils.execute', side_effect=all_repro) as mocked_execute: - result = self.test_target.is_reproducible(self.testcase_path, - self.fuzz_target_path) + result = self.target.is_reproducible(self.testcase_path, + self.fuzz_target_path) mocked_execute.assert_called_once_with([ 'docker', 'run', '--rm', '--privileged', '--cap-add', 'SYS_PTRACE', '-e', 'FUZZING_ENGINE=libfuzzer', '-e', 'ARCHITECTURE=x86_64', '-e', - 'CIFUZZ=True', '-e', 'SANITIZER=' + self.test_target.config.sanitizer, - '-e', 'FUZZING_LANGUAGE=' + self.test_target.config.language, '-e', + 'CIFUZZ=True', '-e', 'SANITIZER=' + self.target.config.sanitizer, + '-e', 'FUZZING_LANGUAGE=' + self.target.config.language, '-e', 'OUT=' + self.workspace.out, '--volumes-from', 'container', '-e', 'TESTCASE=' + self.testcase_path, '-t', 'gcr.io/oss-fuzz-base/base-runner', 'reproduce', @@ -116,8 +116,8 @@ class IsReproducibleTest(fake_filesystem_unittest.TestCase): with mock.patch('utils.execute', side_effect=last_time_repro) as mocked_execute: self.assertTrue( - self.test_target.is_reproducible(self.testcase_path, - self.fuzz_target_path)) + self.target.is_reproducible(self.testcase_path, + self.fuzz_target_path)) self.assertEqual(fuzz_target.REPRODUCE_ATTEMPTS, mocked_execute.call_count) @@ -125,7 +125,7 @@ class IsReproducibleTest(fake_filesystem_unittest.TestCase): """Tests that is_reproducible raises an error if it could not attempt reproduction because the fuzzer doesn't exist.""" with self.assertRaises(fuzz_target.ReproduceError): - self.test_target.is_reproducible(self.testcase_path, '/non-existent-path') + self.target.is_reproducible(self.testcase_path, '/non-existent-path') def test_unreproducible(self, _): """Tests that is_reproducible returns False for a crash that did not @@ -133,8 +133,8 @@ class IsReproducibleTest(fake_filesystem_unittest.TestCase): all_unrepro = [EXECUTE_SUCCESS_RETVAL] * fuzz_target.REPRODUCE_ATTEMPTS self._set_up_fakefs() with mock.patch('utils.execute', side_effect=all_unrepro): - result = self.test_target.is_reproducible(self.testcase_path, - self.fuzz_target_path) + result = self.target.is_reproducible(self.testcase_path, + self.fuzz_target_path) self.assertFalse(result) @@ -169,9 +169,9 @@ class IsCrashReportableTest(fake_filesystem_unittest.TestCase): """Sets up example fuzz target to test is_crash_reportable method.""" self.fuzz_target_path = '/example/do_stuff_fuzzer' deployment = _create_deployment() - self.test_target = fuzz_target.FuzzTarget(self.fuzz_target_path, 100, - '/example/outdir', deployment, - deployment.config) + self.target = fuzz_target.FuzzTarget(self.fuzz_target_path, 100, + '/example/outdir', deployment, + deployment.config) self.oss_fuzz_build_path = '/oss-fuzz-build' self.setUpPyfakefs() self.fs.create_file(self.fuzz_target_path) @@ -190,8 +190,8 @@ class IsCrashReportableTest(fake_filesystem_unittest.TestCase): def test_new_reproducible_crash(self, mocked_info, _): """Tests that a new reproducible crash returns True.""" with tempfile.TemporaryDirectory() as tmp_dir: - self.test_target.out_dir = tmp_dir - self.assertTrue(self.test_target.is_crash_reportable(self.testcase_path)) + self.target.out_dir = tmp_dir + self.assertTrue(self.target.is_crash_reportable(self.testcase_path)) mocked_info.assert_called_with( 'The crash is not reproducible on previous build. ' 'Code change (pr/commit) introduced crash.') @@ -215,8 +215,7 @@ class IsCrashReportableTest(fake_filesystem_unittest.TestCase): side_effect=is_reproducible_retvals): with mock.patch('clusterfuzz_deployment.OSSFuzz.download_latest_build', return_value=self.oss_fuzz_build_path): - self.assertFalse( - self.test_target.is_crash_reportable(self.testcase_path)) + self.assertFalse(self.target.is_crash_reportable(self.testcase_path)) @mock.patch('logging.info') @mock.patch('fuzz_target.FuzzTarget.is_reproducible', return_value=[True]) @@ -236,8 +235,7 @@ class IsCrashReportableTest(fake_filesystem_unittest.TestCase): side_effect=is_reproducible_side_effect) as mocked_is_reproducible: with mock.patch('clusterfuzz_deployment.OSSFuzz.download_latest_build', return_value=self.oss_fuzz_build_path): - self.assertTrue(self.test_target.is_crash_reportable( - self.testcase_path)) + self.assertTrue(self.target.is_crash_reportable(self.testcase_path)) mocked_is_reproducible.assert_any_call(self.testcase_path, self.oss_fuzz_target_path) mocked_info.assert_called_with( |