blob: 3f1984598a3f1b5aa7aa6f248c8d0f230f7725ea [file] [log] [blame]
# 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)