def engine_fuzz(engine_impl, target_name, sync_corpus_directory, testcase_directory): """Run engine fuzzer on untrusted worker.""" request = untrusted_runner_pb2.EngineFuzzRequest( engine=engine_impl.name, target_name=target_name, sync_corpus_directory=file_host.rebase_to_worker_root( sync_corpus_directory), testcase_directory=file_host.rebase_to_worker_root(testcase_directory)) response = host.stub().EngineFuzz(request) crashes = [ engine.Crash( input_path=file_host.rebase_to_host_root(crash.input_path), stacktrace=crash.stacktrace, reproduce_args=crash.reproduce_args, crash_time=crash.crash_time) for crash in response.crashes ] unpacked_stats = _unpack_values(response.stats) unpacked_strategies = _unpack_values(response.strategies) result = engine.FuzzResult( logs=response.logs, command=list(response.command), crashes=crashes, stats=unpacked_stats, time_executed=response.time_executed) file_host.pull_testcases_from_worker() return result, dict(response.fuzzer_metadata), unpacked_strategies
def engine_fuzz(engine_impl, target_name, sync_corpus_directory, testcase_directory): """Run engine fuzzer on untrusted worker.""" request = untrusted_runner_pb2.EngineFuzzRequest( engine=engine_impl.name, target_name=target_name, sync_corpus_directory=file_host.rebase_to_worker_root( sync_corpus_directory), testcase_directory=file_host.rebase_to_worker_root(testcase_directory)) response = host.stub().EngineFuzz(request) crashes = [ engine.Crash( input_path=file_host.rebase_to_host_root(crash.input_path), stacktrace=utils.decode_to_unicode(crash.stacktrace), reproduce_args=crash.reproduce_args, crash_time=crash.crash_time) for crash in response.crashes ] unpacked_stats = {} for key, packed_value in six.iteritems(response.stats): if packed_value.Is(wrappers_pb2.DoubleValue.DESCRIPTOR): value = wrappers_pb2.DoubleValue() elif packed_value.Is(wrappers_pb2.Int32Value.DESCRIPTOR): value = wrappers_pb2.Int32Value() elif packed_value.Is(wrappers_pb2.StringValue.DESCRIPTOR): value = wrappers_pb2.StringValue() else: raise ValueError('Unknown stat type for ' + key) packed_value.Unpack(value) unpacked_stats[key] = value.value result = engine.FuzzResult( logs=utils.decode_to_unicode(response.logs), command=list(response.command), crashes=crashes, stats=unpacked_stats, time_executed=response.time_executed) file_host.pull_testcases_from_worker() return result, dict(response.fuzzer_metadata)
def test_pulling_testcases_from_worker(self): """Test pulling testcases from the worker.""" fuzz_inputs = os.environ['FUZZ_INPUTS'] worker_fuzz_inputs = file_host.rebase_to_worker_root(fuzz_inputs) with open(os.path.join(fuzz_inputs, 'will_be_replaced'), 'w') as f: f.write('blah') with open(os.path.join(worker_fuzz_inputs, 'file'), 'w') as f: f.write('file') subdir = os.path.join(worker_fuzz_inputs, 'subdir') os.mkdir(subdir) with open(os.path.join(subdir, 'file2'), 'w') as f: f.write('file2') self.assertTrue(file_host.pull_testcases_from_worker()) self.assert_dirs_equal(fuzz_inputs, worker_fuzz_inputs)
def run_testcase_and_return_result_in_queue(crash_queue, thread_index, file_path, gestures, env_copy, upload_output=False): """Run a single testcase and return crash results in the crash queue.""" # Since this is running in its own process, initialize the log handler again. # This is needed for Windows where instances are not shared across child # processes. See: # https://stackoverflow.com/questions/34724643/python-logging-with-multiprocessing-root-logger-different-in-windows logs.configure('run_testcase', { 'testcase_path': file_path, }) try: # Run testcase and check whether a crash occurred or not. return_code, crash_time, output = run_testcase(thread_index, file_path, gestures, env_copy) # Pull testcase directory to host to get any stats files. if environment.is_trusted_host(): from bot.untrusted_runner import file_host file_host.pull_testcases_from_worker() # Analyze the crash. crash_output = _get_crash_output(output) crash_result = CrashResult(return_code, crash_time, crash_output) # To provide consistency between stats and logs, we use timestamp taken # from stats when uploading logs and testcase. if upload_output: log_time = _get_testcase_time(file_path) if crash_result.is_crash(): # Initialize resource list with the testcase path. resource_list = [file_path] resource_list += get_resource_paths(crash_output) # Store the crash stack file in the crash stacktrace directory # with filename as the hash of the testcase path. crash_stacks_directory = environment.get_value( 'CRASH_STACKTRACES_DIR') stack_file_path = os.path.join(crash_stacks_directory, utils.string_hash(file_path)) utils.write_data_to_file(crash_output, stack_file_path) # Put crash/no-crash results in the crash queue. crash_queue.put( Crash(file_path=file_path, crash_time=crash_time, return_code=return_code, resource_list=resource_list, gestures=gestures, stack_file_path=stack_file_path)) # Don't upload uninteresting testcases (no crash) or if there is no log to # correlate it with (not upload_output). if upload_output: upload_testcase(file_path, log_time) if upload_output: # Include full output for uploaded logs (crash output, merge output, etc). crash_result_full = CrashResult(return_code, crash_time, output) log = prepare_log_for_upload(crash_result_full.get_stacktrace(), return_code) upload_log(log, log_time) except Exception: logs.log_error('Exception occurred while running ' 'run_testcase_and_return_result_in_queue.')