예제 #1
0
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
예제 #2
0
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
예제 #3
0
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))
예제 #4
0
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))
예제 #5
0
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