| # Copyright 2014 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| """Utility functions used by Generational and Mutational ClusterFuzz |
| fuzzers.""" |
| |
| import argparse |
| import os |
| import random |
| import string |
| import sys |
| import tempfile |
| |
| BUILD_DIR_KEY = 'BUILD_DIR' |
| FLAGS_PREFIX = 'flags-' |
| FUZZ_PREFIX = 'fuzz-' |
| IPC_FUZZER_APPLICATION = 'ipc_fuzzer' |
| IPC_REPLAY_APPLICATION = 'ipc_fuzzer_replay' |
| IPCDUMP_EXTENSION = '.ipcdump' |
| UNCOMMON_PREFIX_CHANCE = 10 # 1 in 10 |
| COMMON_LAUNCH_PREFIXES = [ |
| '--renderer-cmd-prefix', |
| ] |
| UNCOMMON_LAUNCH_PEFIXES = [ |
| '--plugin-launcher', |
| '--ppapi-plugin-launcher', |
| '--utility-cmd-prefix', |
| ] |
| |
| |
| def application_name_for_platform(application_name): |
| """Return application name for current platform.""" |
| if platform() == 'WINDOWS': |
| return application_name + '.exe' |
| return application_name |
| |
| |
| def create_flags_file(ipcdump_testcase_path): |
| """Create a flags file to add launch prefix to application command line.""" |
| prefixes = (UNCOMMON_LAUNCH_PREFIXES if |
| random.randint(1, UNCOMMON_PREFIX_CHANCE) == 1 else |
| COMMON_LAUNCH_PREFIXES) |
| random_launch_prefix = random.choice(prefixes) |
| application_name = application_name_for_platform(IPC_REPLAY_APPLICATION) |
| file_content = '%s=%%APP_DIR%%%s%s' % (random_launch_prefix, os.path.sep, |
| application_name) |
| |
| flags_file_path = ipcdump_testcase_path.replace(FUZZ_PREFIX, FLAGS_PREFIX) |
| file_handle = open(flags_file_path, 'w') |
| file_handle.write(file_content) |
| file_handle.close() |
| |
| |
| def create_temp_file(): |
| """Create a temporary file.""" |
| temp_file = tempfile.NamedTemporaryFile(delete=False) |
| temp_file.close() |
| return temp_file.name |
| |
| |
| def get_fuzzer_application_name(): |
| """Get the application name for the fuzzer binary.""" |
| return application_name_for_platform(IPC_FUZZER_APPLICATION) |
| |
| |
| def get_replay_application_name(): |
| """Get the application name for the replay binary.""" |
| return application_name_for_platform(IPC_REPLAY_APPLICATION) |
| |
| |
| def parse_arguments(): |
| """Parse fuzzer arguments.""" |
| parser = argparse.ArgumentParser() |
| parser.add_argument('--input_dir') |
| parser.add_argument('--output_dir') |
| parser.add_argument('--no_of_files', type=int) |
| args = parser.parse_args() |
| if (not args.input_dir or not args.output_dir or not args.no_of_files): |
| parser.print_help() |
| sys.exit(1) |
| |
| return args |
| |
| |
| def random_id(size=16, chars=string.ascii_lowercase): |
| """Return a random id string, default 16 characters long.""" |
| return ''.join(random.choice(chars) for _ in range(size)) |
| |
| |
| def random_ipcdump_testcase_path(ipcdump_directory): |
| """Return a random ipc testcase path.""" |
| return os.path.join(ipcdump_directory, |
| '%s%s%s' % (FUZZ_PREFIX, random_id(), IPCDUMP_EXTENSION)) |
| |
| |
| def platform(): |
| """Return running platform.""" |
| if sys.platform.startswith('win'): |
| return 'WINDOWS' |
| if sys.platform.startswith('linux'): |
| return 'LINUX' |
| if sys.platform == 'darwin': |
| return 'MAC' |
| |
| assert False, 'Unknown platform' |
| |
| |
| def get_application_path(application_name): |
| """Return chrome application path.""" |
| if BUILD_DIR_KEY not in os.environ: |
| sys.exit('Environment variable %s should be set to chrome directory.' % |
| BUILD_DIR_KEY) |
| |
| for root, _, files in os.walk(os.environ[BUILD_DIR_KEY]): |
| for filename in files: |
| if filename == application_name: |
| return os.path.join(root, application_name) |
| |
| sys.exit('Application %s was not found in chrome directory.' % |
| application_name) |