13f085823Sopenharmony_ci#!/usr/bin/env python 23f085823Sopenharmony_ci# -*- coding:utf-8 -*- 33f085823Sopenharmony_ci# 43f085823Sopenharmony_ci# Copyright (c) 2021 Huawei Device Co., Ltd. 53f085823Sopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); 63f085823Sopenharmony_ci# you may not use this file except in compliance with the License. 73f085823Sopenharmony_ci# You may obtain a copy of the License at 83f085823Sopenharmony_ci# 93f085823Sopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 103f085823Sopenharmony_ci# 113f085823Sopenharmony_ci# Unless required by applicable law or agreed to in writing, software 123f085823Sopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, 133f085823Sopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 143f085823Sopenharmony_ci# See the License for the specific language governing permissions and 153f085823Sopenharmony_ci# limitations under the License. 163f085823Sopenharmony_ci# 173f085823Sopenharmony_ci 183f085823Sopenharmony_cifrom __future__ import print_function 193f085823Sopenharmony_ciimport argparse 203f085823Sopenharmony_ciimport os 213f085823Sopenharmony_ciimport re 223f085823Sopenharmony_ciimport sys 233f085823Sopenharmony_ciimport subprocess 243f085823Sopenharmony_ciimport zipfile 253f085823Sopenharmony_ciimport errno 263f085823Sopenharmony_ciimport pipes 273f085823Sopenharmony_ciimport traceback 283f085823Sopenharmony_ciimport time 293f085823Sopenharmony_ciimport copy 303f085823Sopenharmony_ciimport shutil 313f085823Sopenharmony_cifrom pprint import pprint 323f085823Sopenharmony_ciimport stat 333f085823Sopenharmony_ci 343f085823Sopenharmony_cifrom tools.colored import Colored 353f085823Sopenharmony_cifrom tools.templates import GN_ENTRY_TEMPLATE 363f085823Sopenharmony_cifrom tools.templates import PROJECT_GN_TEMPLATE 373f085823Sopenharmony_cifrom tools.templates import PROJECT_DEMO_TEMPLATE 383f085823Sopenharmony_cifrom tools.templates import PROJECT_HEADER_TEMPLATE 393f085823Sopenharmony_cifrom tools.templates import PROJECT_XML_TEMPLATE 403f085823Sopenharmony_cifrom tools.run_result import RunResult 413f085823Sopenharmony_ci 423f085823Sopenharmony_ciFLAGS = os.O_WRONLY | os.O_CREAT | os.O_EXCL 433f085823Sopenharmony_ciMODES = stat.S_IWUSR | stat.S_IRUSR 443f085823Sopenharmony_ci 453f085823Sopenharmony_ciCURRENT_DIR = os.path.dirname(os.path.realpath(__file__)) 463f085823Sopenharmony_ciSOURCE_ROOT_DIR = os.path.dirname( 473f085823Sopenharmony_ci os.path.dirname( 483f085823Sopenharmony_ci os.path.dirname(os.path.dirname(CURRENT_DIR)) 493f085823Sopenharmony_ci ) 503f085823Sopenharmony_ci ) 513f085823Sopenharmony_ciSOURCE_OUT_DIR = os.path.join(SOURCE_ROOT_DIR, "out") 523f085823Sopenharmony_ci 533f085823Sopenharmony_ciTDD_BUILD_GN_PATH = os.path.join( 543f085823Sopenharmony_ci SOURCE_ROOT_DIR, 553f085823Sopenharmony_ci "test/testfwk/developer_test/BUILD.gn" 563f085823Sopenharmony_ci ) 573f085823Sopenharmony_ci###project name must end with _fuzzer. eg. my_fuzzer,extrator_fuzzer. 583f085823Sopenharmony_ciVALID_PROJECT_NAME_REGEX = re.compile(r'^[a-zA-Z0-9_-]+(_fuzzer)+$') 593f085823Sopenharmony_ci 603f085823Sopenharmony_ci 613f085823Sopenharmony_cidef _add_environment_args(parser): 623f085823Sopenharmony_ci """Add common environment args.""" 633f085823Sopenharmony_ci parser.add_argument( 643f085823Sopenharmony_ci '-t', 653f085823Sopenharmony_ci '--target_platform', 663f085823Sopenharmony_ci default='phone', 673f085823Sopenharmony_ci choices=["phone", "ivi", "plato"], 683f085823Sopenharmony_ci help="set target_platform value, default:phone") 693f085823Sopenharmony_ci 703f085823Sopenharmony_ci parser.add_argument( 713f085823Sopenharmony_ci '-f', 723f085823Sopenharmony_ci '--filter', 733f085823Sopenharmony_ci default=None, 743f085823Sopenharmony_ci help="subsystem filter") 753f085823Sopenharmony_ci 763f085823Sopenharmony_ci 773f085823Sopenharmony_cidef _get_command_string(command): 783f085823Sopenharmony_ci """Returns a shell escaped command string.""" 793f085823Sopenharmony_ci return ' '.join(pipes.quote(part) for part in command) 803f085823Sopenharmony_ci 813f085823Sopenharmony_ci 823f085823Sopenharmony_cidef parse_projects_path(): 833f085823Sopenharmony_ci path_list = [] 843f085823Sopenharmony_ci with open(TDD_BUILD_GN_PATH, 'r') as gn_file: 853f085823Sopenharmony_ci for line in gn_file.readlines()[4:]: 863f085823Sopenharmony_ci striped_str = line.strip() 873f085823Sopenharmony_ci if striped_str.endswith("]"): 883f085823Sopenharmony_ci break 893f085823Sopenharmony_ci path_list.append(striped_str.split(":")[0][3:]) 903f085823Sopenharmony_ci return path_list 913f085823Sopenharmony_ci 923f085823Sopenharmony_ci 933f085823Sopenharmony_cidef _get_fuzzer_yaml_config(fuzzer_name): 943f085823Sopenharmony_ci project_yaml_path = os.path.join( 953f085823Sopenharmony_ci CURRENT_DIR, 963f085823Sopenharmony_ci "projects", 973f085823Sopenharmony_ci fuzzer_name, 983f085823Sopenharmony_ci "project.yaml") 993f085823Sopenharmony_ci if not os.path.exists(project_yaml_path): 1003f085823Sopenharmony_ci return {} 1013f085823Sopenharmony_ci #log run stdout to fuzzlog dir 1023f085823Sopenharmony_ci with open(project_yaml_path) as filehandle: 1033f085823Sopenharmony_ci yaml_config = yaml.safe_load(filehandle) 1043f085823Sopenharmony_ci return yaml_config 1053f085823Sopenharmony_ci 1063f085823Sopenharmony_ci 1073f085823Sopenharmony_ci#generate template fuzzer project 1083f085823Sopenharmony_cidef generate(args): 1093f085823Sopenharmony_ci print("project name %s." % args.project_name) 1103f085823Sopenharmony_ci print("project path %s." % args.project_path) 1113f085823Sopenharmony_ci color_logger = Colored.get_project_logger() 1123f085823Sopenharmony_ci 1133f085823Sopenharmony_ci if not VALID_PROJECT_NAME_REGEX.match(args.project_name): 1143f085823Sopenharmony_ci print('Invalid project name.', file=sys.stderr) 1153f085823Sopenharmony_ci return 1 1163f085823Sopenharmony_ci 1173f085823Sopenharmony_ci template_args = { 1183f085823Sopenharmony_ci 'project_name': args.project_name, 1193f085823Sopenharmony_ci 'author': "", 1203f085823Sopenharmony_ci 'email': "" 1213f085823Sopenharmony_ci } 1223f085823Sopenharmony_ci 1233f085823Sopenharmony_ci project_dir_path = os.path.join(args.project_path, args.project_name) 1243f085823Sopenharmony_ci print("project_dir_path %s." % project_dir_path) 1253f085823Sopenharmony_ci try: 1263f085823Sopenharmony_ci os.mkdir(project_dir_path) 1273f085823Sopenharmony_ci except OSError as os_exception: 1283f085823Sopenharmony_ci if os_exception.errno != errno.EEXIST: 1293f085823Sopenharmony_ci raise 1303f085823Sopenharmony_ci print(color_logger.red('%s already exists.' % project_dir_path), 1313f085823Sopenharmony_ci file=sys.stderr) 1323f085823Sopenharmony_ci return 1 1333f085823Sopenharmony_ci color_logger.green('Writing new files to %s' % project_dir_path) 1343f085823Sopenharmony_ci 1353f085823Sopenharmony_ci file_path = os.path.join(project_dir_path, 'project.xml') 1363f085823Sopenharmony_ci if os.path.exists(file_path): 1373f085823Sopenharmony_ci os.remove(file_path) 1383f085823Sopenharmony_ci with os.fdopen(os.open(file_path, FLAGS, MODES), 'w') as filehandle: 1393f085823Sopenharmony_ci filehandle.write(PROJECT_XML_TEMPLATE % template_args) 1403f085823Sopenharmony_ci 1413f085823Sopenharmony_ci file_path = os.path.join(project_dir_path, "%s.cpp" % args.project_name) 1423f085823Sopenharmony_ci if os.path.exists(file_path): 1433f085823Sopenharmony_ci os.remove(file_path) 1443f085823Sopenharmony_ci with os.fdopen(os.open(file_path, FLAGS, MODES), 'w') as filehandle: 1453f085823Sopenharmony_ci filehandle.write(PROJECT_DEMO_TEMPLATE % template_args) 1463f085823Sopenharmony_ci 1473f085823Sopenharmony_ci file_path = os.path.join(project_dir_path, "%s.h" % args.project_name) 1483f085823Sopenharmony_ci if os.path.exists(file_path): 1493f085823Sopenharmony_ci os.remove(file_path) 1503f085823Sopenharmony_ci with os.fdopen(os.open(file_path, FLAGS, MODES), 'w') as filehandle: 1513f085823Sopenharmony_ci filehandle.write(PROJECT_HEADER_TEMPLATE % template_args) 1523f085823Sopenharmony_ci file_path = os.path.join(project_dir_path, "BUILD.gn") 1533f085823Sopenharmony_ci if os.path.exists(file_path): 1543f085823Sopenharmony_ci os.remove(file_path) 1553f085823Sopenharmony_ci with os.fdopen(os.open(file_path, FLAGS, MODES), 'w') as filehandle: 1563f085823Sopenharmony_ci filehandle.write(PROJECT_GN_TEMPLATE % template_args) 1573f085823Sopenharmony_ci 1583f085823Sopenharmony_ci corpus_dir = os.path.join(project_dir_path, 'corpus') 1593f085823Sopenharmony_ci if not os.path.exists(corpus_dir): 1603f085823Sopenharmony_ci os.mkdir(corpus_dir) 1613f085823Sopenharmony_ci if os.path.exists(os.path.join(corpus_dir, 'init')): 1623f085823Sopenharmony_ci os.remove(os.path.join(corpus_dir, 'init')) 1633f085823Sopenharmony_ci with os.fdopen(os.open(os.path.join(corpus_dir, 'init'), FLAGS, MODES), 'w') as filehandle: 1643f085823Sopenharmony_ci filehandle.write("FUZZ") 1653f085823Sopenharmony_ci return 0 1663f085823Sopenharmony_ci 1673f085823Sopenharmony_ci 1683f085823Sopenharmony_ci#complie fuzzer project 1693f085823Sopenharmony_cidef make(args, stdout=None): 1703f085823Sopenharmony_ci """make fuzzer module.""" 1713f085823Sopenharmony_ci color_logger = Colored.get_project_logger() 1723f085823Sopenharmony_ci 1733f085823Sopenharmony_ci pre_cmd = ['cd', SOURCE_ROOT_DIR] 1743f085823Sopenharmony_ci build_target_platform = "build_platform=\"%s\"" 1753f085823Sopenharmony_ci 1763f085823Sopenharmony_ci build_script = [ 1773f085823Sopenharmony_ci './build.sh', 1783f085823Sopenharmony_ci '--gn-args', 1793f085823Sopenharmony_ci 'build_example=true', 1803f085823Sopenharmony_ci '--build-target' 1813f085823Sopenharmony_ci ] 1823f085823Sopenharmony_ci build_script.append(args.project_name) 1833f085823Sopenharmony_ci build_script.append("--gn-args") 1843f085823Sopenharmony_ci build_script.append(build_target_platform % args.build_platform) 1853f085823Sopenharmony_ci build_script.append("--product-name") 1863f085823Sopenharmony_ci build_script.append(args.build_platform) 1873f085823Sopenharmony_ci build_script.append("--export-para") 1883f085823Sopenharmony_ci build_script.append("PYCACHE_ENABLE:true") 1893f085823Sopenharmony_ci print("BUILD_SCRIPT %s" % build_script) 1903f085823Sopenharmony_ci final_cmd = "%s && %s" % ( 1913f085823Sopenharmony_ci _get_command_string(pre_cmd), 1923f085823Sopenharmony_ci _get_command_string(build_script) 1933f085823Sopenharmony_ci ) 1943f085823Sopenharmony_ci 1953f085823Sopenharmony_ci color_logger.green('Running:%s' % final_cmd) 1963f085823Sopenharmony_ci 1973f085823Sopenharmony_ci subsystem_src_flag_file_path = os.path.join( 1983f085823Sopenharmony_ci SOURCE_OUT_DIR, 1993f085823Sopenharmony_ci "release/current_build_fuzz_target.txt" 2003f085823Sopenharmony_ci ) 2013f085823Sopenharmony_ci if not os.path.exists(os.path.dirname(subsystem_src_flag_file_path)): 2023f085823Sopenharmony_ci os.makedirs(os.path.dirname(subsystem_src_flag_file_path)) 2033f085823Sopenharmony_ci if os.path.exists(subsystem_src_flag_file_path): 2043f085823Sopenharmony_ci os.remove(subsystem_src_flag_file_path) 2053f085823Sopenharmony_ci with os.fdopen(os.open(subsystem_src_flag_file_path, FLAGS, MODES), 'wb') as file_handle: 2063f085823Sopenharmony_ci file_handle.write(args.project_name.encode()) 2073f085823Sopenharmony_ci 2083f085823Sopenharmony_ci try: 2093f085823Sopenharmony_ci if stdout: 2103f085823Sopenharmony_ci ret = subprocess.check_call(build_script, cwd=SOURCE_ROOT_DIR, 2113f085823Sopenharmony_ci stdout=stdout) 2123f085823Sopenharmony_ci else: 2133f085823Sopenharmony_ci ret = subprocess.check_call(build_script, cwd=SOURCE_ROOT_DIR) 2143f085823Sopenharmony_ci return ret 2153f085823Sopenharmony_ci except subprocess.CalledProcessError: 2163f085823Sopenharmony_ci print("*" * 50) 2173f085823Sopenharmony_ci print("*" * 50) 2183f085823Sopenharmony_ci print( 2193f085823Sopenharmony_ci 'fuzzers {} build failed.'.format(args.project_name), 2203f085823Sopenharmony_ci file=sys.stdout 2213f085823Sopenharmony_ci ) 2223f085823Sopenharmony_ci return -1 2233f085823Sopenharmony_ci 2243f085823Sopenharmony_ci 2253f085823Sopenharmony_cidef report(args): 2263f085823Sopenharmony_ci pass 2273f085823Sopenharmony_ci 2283f085823Sopenharmony_ci 2293f085823Sopenharmony_cidef coverage_all(args): 2303f085823Sopenharmony_ci pass 2313f085823Sopenharmony_ci 2323f085823Sopenharmony_ci 2333f085823Sopenharmony_cidef main(): 2343f085823Sopenharmony_ci parser = argparse.ArgumentParser( 2353f085823Sopenharmony_ci 'fuzzer_helper.py', 2363f085823Sopenharmony_ci description='hydra-fuzz helpers' 2373f085823Sopenharmony_ci ) 2383f085823Sopenharmony_ci subparsers = parser.add_subparsers(dest='command') 2393f085823Sopenharmony_ci 2403f085823Sopenharmony_ci generate_parser = subparsers.add_parser( 2413f085823Sopenharmony_ci 'generate', 2423f085823Sopenharmony_ci help='Generate files for new project.name must end with "_fuzzer".') 2433f085823Sopenharmony_ci generate_parser.add_argument('project_name') 2443f085823Sopenharmony_ci generate_parser.add_argument('project_path') 2453f085823Sopenharmony_ci _add_environment_args(generate_parser) 2463f085823Sopenharmony_ci 2473f085823Sopenharmony_ci make_parser = subparsers.add_parser( 2483f085823Sopenharmony_ci 'make', help='Build a single fuzzer module project. ') 2493f085823Sopenharmony_ci make_parser.add_argument('project_name') 2503f085823Sopenharmony_ci make_parser.add_argument('build_platform') 2513f085823Sopenharmony_ci _add_environment_args(make_parser) 2523f085823Sopenharmony_ci 2533f085823Sopenharmony_ci report_parser = subparsers.add_parser( 2543f085823Sopenharmony_ci 'report', help='Report fuzzer log' 2553f085823Sopenharmony_ci ) 2563f085823Sopenharmony_ci _add_environment_args(report_parser) 2573f085823Sopenharmony_ci report_parser.add_argument( 2583f085823Sopenharmony_ci 'subfunc', 2593f085823Sopenharmony_ci default="list", 2603f085823Sopenharmony_ci choices=["list", "coverage", "all"] 2613f085823Sopenharmony_ci ) 2623f085823Sopenharmony_ci report_parser.add_argument( 2633f085823Sopenharmony_ci "-i", 2643f085823Sopenharmony_ci "--id", 2653f085823Sopenharmony_ci required=False, 2663f085823Sopenharmony_ci help="report ID, e.g. empty_fuzzer.20200211184850" 2673f085823Sopenharmony_ci ) 2683f085823Sopenharmony_ci 2693f085823Sopenharmony_ci args = parser.parse_args() 2703f085823Sopenharmony_ci 2713f085823Sopenharmony_ci if args.command == 'generate': 2723f085823Sopenharmony_ci return generate(args) 2733f085823Sopenharmony_ci elif args.command == 'make': 2743f085823Sopenharmony_ci return make(args) 2753f085823Sopenharmony_ci 2763f085823Sopenharmony_ci elif args.command == 'report': 2773f085823Sopenharmony_ci report(args) 2783f085823Sopenharmony_ci return 1 2793f085823Sopenharmony_ci else: 2803f085823Sopenharmony_ci return 0 2813f085823Sopenharmony_ci 2823f085823Sopenharmony_ciif __name__ == "__main__": 2833f085823Sopenharmony_ci main() 284