def get_runner(fuzzer_path, temp_dir=None): """Get a libfuzzer runner.""" use_minijail = environment.get_value('USE_MINIJAIL') build_dir = environment.get_value('BUILD_DIR') dataflow_build_dir = environment.get_value('DATAFLOW_BUILD_DIR') if use_minijail: # Set up chroot and runner. if environment.is_chromeos_system_job(): minijail_chroot = minijail.ChromeOSChroot(build_dir) else: minijail_chroot = minijail.MinijailChroot(base_dir=temp_dir) # While it's possible for dynamic binaries to run without this, they need # to be accessible for symbolization etc. For simplicity we bind BUILD_DIR # to the same location within the chroot, which leaks the directory # structure of CF but this shouldn't be a big deal. minijail_chroot.add_binding( minijail.ChrootBinding(build_dir, build_dir, False)) if dataflow_build_dir: minijail_chroot.add_binding( minijail.ChrootBinding(dataflow_build_dir, dataflow_build_dir, False)) # Also bind the build dir to /out to make it easier to hardcode references # to data files. minijail_chroot.add_binding( minijail.ChrootBinding(build_dir, '/out', False)) minijail_bin = os.path.join(minijail_chroot.directory, 'bin') shell.create_directory(minijail_bin) # Set up /bin with llvm-symbolizer to allow symbolized stacktraces. # Don't copy if it already exists (e.g. ChromeOS chroot jail). llvm_symbolizer_source_path = environment.get_llvm_symbolizer_path() llvm_symbolizer_destination_path = os.path.join( minijail_bin, 'llvm-symbolizer') if not os.path.exists(llvm_symbolizer_destination_path): shutil.copy(llvm_symbolizer_source_path, llvm_symbolizer_destination_path) # copy /bin/sh, necessary for system(). if not environment.is_chromeos_system_job(): # The chroot has its own shell we don't need to copy (and probably # shouldn't because of library differences). shutil.copy(os.path.realpath('/bin/sh'), os.path.join(minijail_bin, 'sh')) runner = MinijailLibFuzzerRunner(fuzzer_path, minijail_chroot) elif environment.platform() == 'FUCHSIA': runner = FuchsiaQemuLibFuzzerRunner(fuzzer_path) else: runner = LibFuzzerRunner(fuzzer_path) return runner
def filter_binary_path(binary_path): """Filters binary path to provide a local copy.""" platform = environment.platform() if platform == 'ANDROID': # Skip symbolization when running it on bad entries like [stack:XYZ]. if not binary_path.startswith('/') or '(deleted)' in binary_path: return '' # Initialize some helper variables. binary_filename = os.path.basename(binary_path) build_directory = environment.get_value('BUILD_DIR') symbols_directory = environment.get_value('SYMBOLS_DIR') # Try to find the library in the build directory first. local_binary_path = utils.find_binary_path(build_directory, binary_path) if local_binary_path: return local_binary_path # We didn't find the library locally in the build directory. # Try finding the library in the local system library cache. download_system_symbols_if_needed(symbols_directory) local_binary_path = utils.find_binary_path(symbols_directory, binary_path) if local_binary_path: return local_binary_path # Try pulling in the binary directly from the device into the # system library cache directory. local_binary_path = os.path.join(symbols_directory, binary_filename) adb.run_command('pull %s %s' % (binary_path, local_binary_path)) if os.path.exists(local_binary_path): return local_binary_path # Unable to find library. logs.log_error('Unable to find library %s for symbolization.' % binary_path) return '' if platform == 'CHROMEOS': # FIXME: Add code to pull binaries from ChromeOS device. return binary_path if environment.is_chromeos_system_job(): # This conditional is True for ChromeOS system fuzzers that are running on # Linux. Ensure that the binary is always looked for in the chroot and not # in system directories. build_dir = environment.get_value('BUILD_DIR') if not binary_path.startswith(build_dir): # Fixup path so |binary_path| points to a binary in the chroot (probably # a system library). return os.path.join(build_dir, binary_path[1:]) # For Linux and Mac, the binary exists locally. No work to do, # just return the same binary path. return binary_path
def do_fork(): """Return whether or not to do fork mode.""" # TODO(crbug.com/920355): Reenable this when fork mode works with ChromeOS's # MSAN. job_name = environment.get_value('JOB_NAME') memory_tool = environment.get_memory_tool_name(job_name) if memory_tool == 'MSAN' and environment.is_chromeos_system_job(): return False return engine_common.decide_with_probability( engine_common.get_strategy_probability(strategy.FORK_STRATEGY, default=FORK_PROBABILITY))
def do_fork(): """Return whether or not to do fork mode.""" # TODO(metzman): Find a workaround for Windows command line limit before # re-enabling this. if environment.platform() == 'WINDOWS': return False # TODO(crbug.com/920355): Reenable this when fork mode works with ChromeOS's # MSAN. job_name = environment.get_value('JOB_NAME') memory_tool = environment.get_memory_tool_name(job_name) if memory_tool == 'MSAN' and environment.is_chromeos_system_job(): return False return engine_common.decide_with_probability( engine_common.get_strategy_probability(strategy.FORK_STRATEGY, default=FORK_PROBABILITY))
def filter_binary_path(binary_path): """Filters binary path to provide a local copy.""" if environment.is_android() or environment.is_lkl_job(): return symbols_downloader.filter_binary_path(binary_path) if environment.platform() == 'CHROMEOS': # FIXME: Add code to pull binaries from ChromeOS device. return binary_path if environment.is_chromeos_system_job(): # This conditional is True for ChromeOS system fuzzers that are running on # Linux. Ensure that the binary is always looked for in the chroot and not # in system directories. build_dir = environment.get_value('BUILD_DIR') if not binary_path.startswith(build_dir): # Fixup path so |binary_path| points to a binary in the chroot (probably # a system library). return os.path.join(build_dir, binary_path[1:]) # For Linux and Mac, the binary exists locally. No work to do, # just return the same binary path. return binary_path