Commit 49602667 authored by Max Moroz's avatar Max Moroz Committed by Commit Bot

[libFuzzer] Add support for custom *SAN_OPTIONS via GN attribute.

Bug: 539572
Change-Id: Ia3516e8dfbca2521d5c1b7af043ed79072e194a5
Reviewed-on: https://chromium-review.googlesource.com/c/1333895
Commit-Queue: Max Moroz <mmoroz@chromium.org>
Reviewed-by: default avatarAbhishek Arya <inferno@chromium.org>
Reviewed-by: default avatarJonathan Metzman <metzman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#607822}
parent a9072635
...@@ -14,12 +14,15 @@ import("//testing/test.gni") ...@@ -14,12 +14,15 @@ import("//testing/test.gni")
# Supported attributes: # Supported attributes:
# - (required) sources - fuzzer test source files # - (required) sources - fuzzer test source files
# - deps - test dependencies # - deps - test dependencies
# - libs - Additional libraries to link.
# - additional_configs - additional configs to be used for compilation # - additional_configs - additional configs to be used for compilation
# - dict - a dictionary file for the fuzzer. # - dict - a dictionary file for the fuzzer.
# - environment_variables - certain whitelisted environment variables for the # - environment_variables - certain whitelisted environment variables for the
# fuzzer (AFL_DRIVER_DONT_DEFER is the only one allowed currently). # fuzzer (AFL_DRIVER_DONT_DEFER is the only one allowed currently).
# - libfuzzer_options - options for the fuzzer (e.g. -max_len or -timeout). # - libfuzzer_options - options for the fuzzer (e.g. -max_len=N or -timeout=N).
# - libs - Additional libraries to link. # - asan_options - AddressSanitizer options (e.g. allow_user_segv_handler=1).
# - msan_options - MemorySanitizer options.
# - ubsan_options - UndefinedBehaviorSanitizer options.
# - seed_corpus - a directory with seed corpus. # - seed_corpus - a directory with seed corpus.
# - seed_corpus_deps - dependencies for generating the seed corpus. # - seed_corpus_deps - dependencies for generating the seed corpus.
# - skip_owners - if true, skips writing the owners file. # - skip_owners - if true, skips writing the owners file.
...@@ -46,6 +49,10 @@ template("fuzzer_test") { ...@@ -46,6 +49,10 @@ template("fuzzer_test") {
test_deps += invoker.deps test_deps += invoker.deps
} }
if (defined(invoker.libs)) {
libs = invoker.libs
}
if (defined(invoker.seed_corpus) || defined(invoker.seed_corpuses)) { if (defined(invoker.seed_corpus) || defined(invoker.seed_corpuses)) {
assert(!(defined(invoker.seed_corpus) && defined(invoker.seed_corpuses)), assert(!(defined(invoker.seed_corpus) && defined(invoker.seed_corpuses)),
"Do not use both seed_corpus and seed_corpuses for $target_name.") "Do not use both seed_corpus and seed_corpuses for $target_name.")
...@@ -87,6 +94,8 @@ template("fuzzer_test") { ...@@ -87,6 +94,8 @@ template("fuzzer_test") {
} }
if (defined(invoker.dict) || defined(invoker.libfuzzer_options) || if (defined(invoker.dict) || defined(invoker.libfuzzer_options) ||
defined(invoker.asan_options) || defined(invoker.msan_options) ||
defined(invoker.ubsan_options) ||
defined(invoker.environment_variables)) { defined(invoker.environment_variables)) {
if (defined(invoker.dict)) { if (defined(invoker.dict)) {
# Copy dictionary to output. # Copy dictionary to output.
...@@ -123,8 +132,19 @@ template("fuzzer_test") { ...@@ -123,8 +132,19 @@ template("fuzzer_test") {
args += invoker.libfuzzer_options args += invoker.libfuzzer_options
} }
if (defined(invoker.libs)) { if (defined(invoker.asan_options)) {
libs = invoker.libs args += [ "--asan_options" ]
args += invoker.asan_options
}
if (defined(invoker.msan_options)) {
args += [ "--msan_options" ]
args += invoker.msan_options
}
if (defined(invoker.ubsan_options)) {
args += [ "--ubsan_options" ]
args += invoker.ubsan_options
} }
if (defined(invoker.environment_variables)) { if (defined(invoker.environment_variables)) {
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
# Copyright (c) 2015 The Chromium Authors. All rights reserved. # Copyright (c) 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
"""Generate or update an existing config (.options file) for libfuzzer test. """Generate or update an existing config (.options file) for libfuzzer test.
Invoked by GN from fuzzer_test.gni. Invoked by GN from fuzzer_test.gni.
...@@ -14,10 +13,14 @@ import argparse ...@@ -14,10 +13,14 @@ import argparse
import os import os
import sys import sys
def AddSectionOptions(config, section_name, options): def AddSectionOptions(config, section_name, options):
"""Add |options| to the |section_name| section of |config|. Throws an """Add |options| to the |section_name| section of |config|.
Throws an
assertion error if any option in |options| does not have exactly two assertion error if any option in |options| does not have exactly two
elements.""" elements.
"""
if not options: if not options:
return return
...@@ -30,29 +33,46 @@ def AddSectionOptions(config, section_name, options): ...@@ -30,29 +33,46 @@ def AddSectionOptions(config, section_name, options):
def main(): def main():
parser = argparse.ArgumentParser(description="Generate fuzzer config.") parser = argparse.ArgumentParser(description='Generate fuzzer config.')
parser.add_argument('--config', required=True) parser.add_argument('--config', required=True)
parser.add_argument('--dict') parser.add_argument('--dict')
parser.add_argument('--libfuzzer_options', nargs='+', default=[]) parser.add_argument('--libfuzzer_options', nargs='+', default=[])
parser.add_argument('--environment_variables', nargs='+', default=[], parser.add_argument('--asan_options', nargs='+', default=[])
choices=['AFL_DRIVER_DONT_DEFER=1']) parser.add_argument('--msan_options', nargs='+', default=[])
parser.add_argument('--ubsan_options', nargs='+', default=[])
parser.add_argument(
'--environment_variables',
nargs='+',
default=[],
choices=['AFL_DRIVER_DONT_DEFER=1'])
args = parser.parse_args() args = parser.parse_args()
# Script shouldn't be invoked without any arguments, but just in case. # Script shouldn't be invoked without any arguments, but just in case.
if not (args.dict or args.libfuzzer_options or args.environment_variables): if not (args.dict or args.libfuzzer_options or args.environment_variables or
args.asan_options or args.msan_options or args.ubsan_options):
return return
config = ConfigParser.ConfigParser() config = ConfigParser.ConfigParser()
libfuzzer_options = [] libfuzzer_options = []
if args.dict: if args.dict:
libfuzzer_options.append(('dict', os.path.basename(args.dict))) libfuzzer_options.append(('dict', os.path.basename(args.dict)))
libfuzzer_options.extend(option.split('=') libfuzzer_options.extend(
for option in args.libfuzzer_options) option.split('=') for option in args.libfuzzer_options)
AddSectionOptions(config, 'libfuzzer', libfuzzer_options) AddSectionOptions(config, 'libfuzzer', libfuzzer_options)
AddSectionOptions(config, 'env',
[option.split('=') for option in args.environment_variables] AddSectionOptions(config, 'asan',
) [option.split('=') for option in args.asan_options])
AddSectionOptions(config, 'msan',
[option.split('=') for option in args.msan_options])
AddSectionOptions(config, 'ubsan',
[option.split('=') for option in args.ubsan_options])
AddSectionOptions(
config, 'env',
[option.split('=') for option in args.environment_variables])
# Generate .options file. # Generate .options file.
config_path = args.config config_path = args.config
...@@ -61,5 +81,6 @@ def main(): ...@@ -61,5 +81,6 @@ def main():
'# This is an automatically generated config for ClusterFuzz.\n') '# This is an automatically generated config for ClusterFuzz.\n')
config.write(options_file) config.write(options_file)
if __name__ == '__main__': if __name__ == '__main__':
main() main()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment