提交 85ea2157 编写于 作者: O openharmony_ci 提交者: Gitee

!35 adapt fuzz test template

Merge pull request !35 from NicoYam/master
......@@ -35,6 +35,9 @@
<option name="SEC"
desc="security"
timeout="900" />
<option name="FUZZ"
desc="fuzztest"
timeout="900" />
<option name="RELI"
desc="reliability"
timeout="900" />
......
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2021 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<fuzz_config>
<fuzztest>
<!-- maximum length of a test input -->
<max_len>1000</max_len>
<!-- maximum total time in seconds to run the fuzzer -->
<max_total_time>300</max_total_time>
<!-- memory usage limit in Mb -->
<rss_limit_mb>4096</rss_limit_mb>
</fuzztest>
</fuzz_config>
......@@ -24,4 +24,11 @@ group("unittest") {
deps += [ "unittest/phone:unittest" ]
}
}
group("fuzztest") {
testonly = true
deps = []
deps += [ "fuzztest/common/parse_fuzzer:fuzztest" ]
}
###############################################################################
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/config/features.gni")
import("//build/test.gni")
module_output_path = "subsystem_examples/calculator"
##############################fuzztest##########################################
ohos_fuzztest("CalculatorFuzzTest") {
module_out_path = module_output_path
include_dirs = []
cflags = [
"-g",
"-O0",
"-Wno-unused-variable",
"-fno-omit-frame-pointer",
]
sources = [ "parse_fuzzer.cpp" ]
}
###############################################################################
group("fuzztest") {
testonly = true
deps = []
deps += [
# deps file
":CalculatorFuzzTest",
]
}
###############################################################################
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "parse_fuzzer.h"
#include <stddef.h>
#include <stdint.h>
const int FUZZ_DATA_LEN = 3;
const int FUZZ_FST_DATA = 0;
const int FUZZ_SND_DATA = 1;
const int FUZZ_TRD_DATA = 2;
const int FUZZ_FTH_DATA = 3;
namespace OHOS {
bool DoSomethingInterestingWithMyAPI(const uint8_t* data, size_t size)
{
bool result = false;
if (size >= FUZZ_DATA_LEN) {
result = data[FUZZ_FST_DATA] == 'F' &&
data[FUZZ_SND_DATA] == 'U' &&
data[FUZZ_TRD_DATA] == 'Z' &&
data[FUZZ_FTH_DATA] == 'Z';
}
return result;
}
}
/* Fuzzer entry point */
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
/* Run your code on data */
OHOS::DoSomethingInterestingWithMyAPI(data, size);
return 0;
}
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cstdint>
#include <unistd.h>
#include <climits>
#include <cstdio>
#include <cstdlib>
#include <fcntl.h>
#define FUZZ_PROJECT_NAME "parse_fuzzer"
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2021 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<fuzz_config>
<fuzztest>
<!-- maximum length of a test input -->
<max_len>1000</max_len>
<!-- maximum total time in seconds to run the fuzzer -->
<max_total_time>300</max_total_time>
<!-- memory usage limit in Mb -->
<rss_limit_mb>4096</rss_limit_mb>
</fuzztest>
</fuzz_config>
......@@ -9,6 +9,7 @@
],
"test_list": [
"//test/developertest/examples/calculator/test:unittest",
"//test/developertest/examples/calculator/test:fuzztest",
"//test/developertest/examples/detector/test:unittest",
"//test/developertest/examples/sleep/test:performance",
"//test/developertest/examples/distributedb/test:distributedtest"
......
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("///build/config/sanitizers/sanitizers.gni")
fuzzing_engine_remove_configs = [
"//build/config/coverage:default_coverage",
"//build/config/sanitizers:default_sanitizer_flags",
]
fuzzing_engine_add_configs =
[ "//build/config/sanitizers:default_sanitizer_flags_but_coverage" ]
source_set("libfuzzer") {
sources = [
"//third_party/llvm-project/compiler-rt/lib/fuzzer/FuzzerCrossOver.cpp",
"//third_party/llvm-project/compiler-rt/lib/fuzzer/FuzzerDataFlowTrace.cpp",
"//third_party/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp",
"//third_party/llvm-project/compiler-rt/lib/fuzzer/FuzzerExtFunctionsDlsym.cpp",
"//third_party/llvm-project/compiler-rt/lib/fuzzer/FuzzerExtFunctionsWeak.cpp",
"//third_party/llvm-project/compiler-rt/lib/fuzzer/FuzzerExtFunctionsWindows.cpp",
"//third_party/llvm-project/compiler-rt/lib/fuzzer/FuzzerExtraCounters.cpp",
"//third_party/llvm-project/compiler-rt/lib/fuzzer/FuzzerFork.cpp",
"//third_party/llvm-project/compiler-rt/lib/fuzzer/FuzzerIO.cpp",
"//third_party/llvm-project/compiler-rt/lib/fuzzer/FuzzerIOPosix.cpp",
"//third_party/llvm-project/compiler-rt/lib/fuzzer/FuzzerIOWindows.cpp",
"//third_party/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp",
"//third_party/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp",
"//third_party/llvm-project/compiler-rt/lib/fuzzer/FuzzerMerge.cpp",
"//third_party/llvm-project/compiler-rt/lib/fuzzer/FuzzerMutate.cpp",
"//third_party/llvm-project/compiler-rt/lib/fuzzer/FuzzerSHA1.cpp",
"//third_party/llvm-project/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp",
"//third_party/llvm-project/compiler-rt/lib/fuzzer/FuzzerUtil.cpp",
"//third_party/llvm-project/compiler-rt/lib/fuzzer/FuzzerUtilDarwin.cpp",
"//third_party/llvm-project/compiler-rt/lib/fuzzer/FuzzerUtilFuchsia.cpp",
"//third_party/llvm-project/compiler-rt/lib/fuzzer/FuzzerUtilLinux.cpp",
"//third_party/llvm-project/compiler-rt/lib/fuzzer/FuzzerUtilPosix.cpp",
]
configs -= fuzzing_engine_remove_configs
configs += fuzzing_engine_add_configs
}
if (use_afl) {
source_set("afl_driver") {
sources = [ "src/afl/afl_driver.cpp" ]
configs -= fuzzing_engine_remove_configs
configs += fuzzing_engine_add_configs
}
}
# 测试框架DTFuzz测试指导
## 简介
模糊测试(fuzzing test)是一种软件测试技术,其核心思想是将自动或半自动生成的随机数据输入到一个程序中,并监视程序异常,如崩溃,断言(assertion)失败,以发现可能的程序错误,比如内存泄漏,访问越界等。
使用测试框架DTFuzz,需要完成DTFuzz初始化、DTFuzz用例编写、DTFuzz用例编译和DTFuzz用例执行几步。
## 使用测试框架DTFuzz
- 测试框架配置
文件:config/user_config.xml
配置测试用例的编译参数
```
<build>
<example>false</example>
<version>false</version>
<testcase>true</testcase>
... ...
</build>
```
![img](https://gitee.com/nicoyam/test_developertest/raw/master/public_sys-resources/icon-note.gif) **说明:** 测试用例的编译参数说明如下:
example:是否编译测试用例示例,默认false。
version:是否编译测试版本,默认false。
testcase:是否编译测试用例,默认true。
- 启动测试框架
打开test/developertest目录,Windows环境启动测试框架执行
```
start.bat
```
Linux环境启动测试框架执行
```
./strat.sh
```
- 设备形态选择
根据实际的开发板选择,设备形态配置:developertest/config/framework_config.xml。
- 单个DTFuzz初始化
1. DTFuzz源文件生成
执行gen命令用于DTFuzz源文件生成,会自动生成DTFuzz源文件、DTFuzz options配置文件和corpus语料,目录结构如下
```
parse_fuzzer/
├── corpus # DTFuzz语料目录
│ ├── init # DTFuzz语料
├── BUILD.gn # DTFuzz用例编译配置
├── parse_fuzzer.cpp # DTFuzz用例源文件
├── parse_fuzzer.h # DTFuzz用例头文件
├── project.xml # DTFuzz选项配置文件
```
2. 命令参数说明,参数可以指定DTFuzz名称和DTFuzz路径
```
gen -t TESTTYPE -fn FUZZERNAME -dp DIRECTORYPATH
```
| 参数 | 说明 | 备注 |
| ---- | -------------- | -------------------------------------------------------- |
| -t | 测试类型 | 目前仅支持"FUZZ" |
| -fn | DTFuzz名称 | 为显式区分DTFuzz,名称必须以"fuzzer"结尾 |
| -dp | DTFuzz生成路径 | 执行命令前需要手动创建fuzztest目录和对应形态目录如common |
3. gen命令示例,-t、-fn和-dp均为必选项
```
gen -t FUZZ -fn parse_fuzzer -dp test/developertest/example/calculator/test/fuzztest/common
```
- DTFuzz用例编写
1. 源文件编写
DTFuzz用例主要在${DTFuzz名称}.cpp源文件中,一个DTFuzz仅支持一个接口进行fuzz测试。
源文件包含两个接口:
| 接口 | 说明 |
| ------------------------------- | -------------------------------- |
| LLVMFuzzerTestOneInput | DTFuzz入口函数,由Fuzz框架调用 |
| DoSomethingInterestingWithMyAPI | 被测试接口,实现各业务被测试逻辑 |
![img](https://gitee.com/nicoyam/test_developertest/raw/master/public_sys-resources/icon-note.gif) **说明:** DoSomethingInterestingWithMyAPI接口名称允许依据业务逻辑修改。两接口参数data和size为fuzz测试标准化参数,不可修改。
2. BUILD.gn编写
[ohos_fuzztest] # 配置DTFuzz模板,例如:
```
ohos_fuzztest("CalculatorFuzzTest") { #定义测试套名称CalculatorFuzzTest
module_out_path = module_output_path
include_dirs = []
cflags = [
"-g",
"-O0",
"-Wno-unused-variable",
"-fno-omit-frame-pointer",
]
sources = [ "parse_fuzzer.cpp" ]
}
```
[group] # 引用测试套,例如:
```
group("fuzztest") {
testonly = true
deps = []
deps += [
# deps file
":CalculatorFuzzTest", #引用测试套
]
}
```
3. DTFuzz配置编写
project.xml为DTFuzz参数配置文件,包括:
```
<!-- maximum length of a test input -->
<max_len>1000</max_len>
<!-- maximum total time in seconds to run the DTFuzz -->
<max_total_time>300</max_total_time>
<!-- memory usage limit in Mb -->
<rss_limit_mb>4096</rss_limit_mb>
```
- DTFuzz用例编译
添加DTFuzz用例编译:
1. 在需要DTFuzz测试的对应模块ohos.build添加DTFuzz用例路径,如在examples/ohos.build添加:
```
"test_list": [
"//test/developertest/examples/calculator/test:unittest",
"//test/developertest/examples/calculator/test:fuzztest", #添加DTFuzz用例路径
"//test/developertest/examples/detector/test:unittest",
"//test/developertest/examples/sleep/test:performance",
"//test/developertest/examples/distributedb/test:distributedtest"
]
```
2. 在用例路径下的BUILD.gn添加group,如examples/calculator/test的BUILD.gn
```
group("fuzztest") {
testonly = true
deps = []
deps += [ "fuzztest/common/parse_fuzzer:fuzztest" ]
}
```
- DTFuzz用例执行
DTFuzz能力集成在测试类型-t中新增FUZZ类型,执行DTFuzz测试指令示例,其中-t为必选,-ss和-tm为可选
```
run -t FUZZ -ss subsystem_examples -tm calculator
```
## 测试结果与日志
- 通过在测试框架中执行测试指令,即可以生成测试日志和测试报告。
- 测试结果
测试用例的结果会直接显示在控制台上,执行一次的测试结果根路径如下:
```
reports/xxxx-xx-xx-xx-xx-xx
```
测试用例格式化结果
```
result/
```
测试用例日志
```
log/plan_log_xxxx-xx-xx-xx-xx-xx.log
```
测试报告汇总
```
summary_report.html
```
测试报告详情
```
details_report.html
```
最新测试报告
```
reports/latest
```
#!/usr/bin/env python
# -*- coding:utf-8 -*-
#
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
from __future__ import print_function
import argparse
import os
import re
import sys
import subprocess
import zipfile
import errno
import pipes
import traceback
import time
import copy
from tools.colored import Colored
from tools.templates import GN_ENTRY_TEMPLATE
from tools.templates import PROJECT_GN_TEMPLATE
from tools.templates import PROJECT_DEMO_TEMPLATE
from tools.templates import PROJECT_HEADER_TEMPLATE
from tools.templates import PROJECT_XML_TEMPLATE
import shutil
from pprint import pprint
from tools.run_result import RunResult
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
SOURCE_ROOT_DIR = os.path.dirname(
os.path.dirname(
os.path.dirname(os.path.dirname(CURRENT_DIR))
)
)
SOURCE_OUT_DIR = os.path.join(SOURCE_ROOT_DIR, "out")
TDD_BUILD_GN_PATH = os.path.join(
SOURCE_ROOT_DIR,
"test/developertest/BUILD.gn"
)
###project name must end with _fuzzer. eg. my_fuzzer,extrator_fuzzer.
VALID_PROJECT_NAME_REGEX = re.compile(r'^[a-zA-Z0-9_-]+(_fuzzer)+$')
def _add_environment_args(parser):
"""Add common environment args."""
parser.add_argument(
'-t',
'--target_platform',
default='phone',
choices=["phone", "ivi", "plato"],
help="set target_platform value, default:phone")
parser.add_argument(
'-f',
'--filter',
default=None,
help="subsystem filter")
def _get_command_string(command):
"""Returns a shell escaped command string."""
return ' '.join(pipes.quote(part) for part in command)
def parse_projects_path():
path_list = []
with open(TDD_BUILD_GN_PATH, 'r') as gn_file:
for line in gn_file.readlines()[4:]:
striped_str = line.strip()
if striped_str.endswith("]"):
break
path_list.append(striped_str.split(":")[0][3:])
return path_list
def _get_fuzzer_yaml_config(fuzzer_name):
project_yaml_path = os.path.join(
CURRENT_DIR,
"projects",
fuzzer_name,
"project.yaml")
if not os.path.exists(project_yaml_path):
return None
#log run stdout to fuzzlog dir
with open(project_yaml_path) as filehandle:
yaml_config = yaml.safe_load(filehandle)
return yaml_config
#generate template fuzzer project
def generate(args):
print("project name %s." % args.project_name)
print("project path %s." % args.project_path)
color_logger = Colored.get_project_logger()
if not VALID_PROJECT_NAME_REGEX.match(args.project_name):
print('Invalid project name.', file=sys.stderr)
return 1
template_args = {
'project_name': args.project_name,
'author': "@fixme",
'email': "@fixme"
}
project_dir_path = os.path.join(args.project_path, args.project_name)
print("project_dir_path %s." % project_dir_path)
try:
os.mkdir(project_dir_path)
except OSError as os_exception:
if os_exception.errno != errno.EEXIST:
raise
print(color_logger.red('%s already exists.' % project_dir_path),
file=sys.stderr)
return 1
color_logger.green('Writing new files to %s' % project_dir_path)
file_path = os.path.join(project_dir_path, 'project.xml')
with open(file_path, 'w') as filehandle:
filehandle.write(PROJECT_XML_TEMPLATE % template_args)
file_path = os.path.join(project_dir_path, "%s.cc" % args.project_name)
with open(file_path, 'w') as filehandle:
filehandle.write(PROJECT_DEMO_TEMPLATE % template_args)
file_path = os.path.join(project_dir_path, "%s.h" % args.project_name)
with open(file_path, 'w') as filehandle:
filehandle.write(PROJECT_HEADER_TEMPLATE % template_args)
file_path = os.path.join(project_dir_path, "BUILD.gn")
with open(file_path, 'w') as filehandle:
filehandle.write(PROJECT_GN_TEMPLATE % template_args)
corpus_dir = os.path.join(project_dir_path, 'corpus')
if not os.path.exists(corpus_dir):
os.mkdir(corpus_dir)
with open(os.path.join(corpus_dir, 'init'), 'w') as filehandle:
filehandle.write("FUZZ")
#complie fuzzer project
def make(args, stdout=None):
"""make fuzzer module."""
color_logger = Colored.get_project_logger()
pre_cmd = ['cd', SOURCE_ROOT_DIR]
build_target_platform = "build_platform=\"%s\""
build_script = [
'./build.sh',
'--gn-args',
'build_example=true',
'--target-variant sanitizer',
'--build-target'
]
build_script.append(args.project_name)
build_script.append("--gn-args")
build_script.append(build_target_platform % args.build_platform)
build_script.append("--product-name")
build_script.append(args.build_platform)
build_script.append("--export-para")
build_script.append("PYCACHE_ENABLE:true")
build_script.append("--export-para")
build_script.append("BUILD_AOSP:false")
print("BUILD_SCRIPT %s" % build_script)
final_cmd = "%s && %s" % (
_get_command_string(pre_cmd),
_get_command_string(build_script)
)
color_logger.green('Running:%s' % final_cmd)
subsystem_src_flag_file_path = os.path.join(
SOURCE_OUT_DIR,
"release/current_build_fuzz_target.txt"
)
if not os.path.exists(os.path.dirname(subsystem_src_flag_file_path)):
os.makedirs(os.path.dirname(subsystem_src_flag_file_path))
with open(subsystem_src_flag_file_path, "wb") as file_handle:
file_handle.write(args.project_name.encode())
try:
if stdout:
ret = subprocess.check_call(build_script, cwd=SOURCE_ROOT_DIR,
stdout=stdout)
else:
ret = subprocess.check_call(build_script, cwd=SOURCE_ROOT_DIR)
return ret
except subprocess.CalledProcessError:
print("*"*50)
print("*"*50)
print(
'fuzzers {} build failed.'.format(args.project_name),
file=sys.stdout
)
return -1
def report(args):
pass
def coverage_all(args):
pass
def main():
parser = argparse.ArgumentParser(
'fuzzer_helper.py',
description='hydra-fuzz helpers'
)
subparsers = parser.add_subparsers(dest='command')
generate_parser = subparsers.add_parser(
'generate',
help='Generate files for new project.name must end with "_fuzzer".')
generate_parser.add_argument('project_name')
generate_parser.add_argument('project_path')
_add_environment_args(generate_parser)
make_parser = subparsers.add_parser(
'make', help='Build a single fuzzer module project. ')
make_parser.add_argument('project_name')
make_parser.add_argument('build_platform')
_add_environment_args(make_parser)
report_parser = subparsers.add_parser(
'report', help='Report fuzzer log'
)
_add_environment_args(report_parser)
report_parser.add_argument(
'subfunc',
default="list",
choices=["list", "coverage", "all"]
)
report_parser.add_argument(
"-i",
"--id",
required=False,
help="report ID, e.g. empty_fuzzer.20200211184850"
)
args = parser.parse_args()
if args.command == 'generate':
return generate(args)
elif args.command == 'make':
return make(args)
elif args.command == 'report':
report(args)
if __name__ == "__main__":
main()
#!/usr/bin/env python
# -*- coding:utf-8 -*-
#
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import sys
import os
import time
class Colored(object):
RED = '\033[1;31m'
GREEN = '\033[1;32m'
YELLOW = '\033[1;33m'
BLUE = '\033[1;34m'
FUCHSIA = '\033[1;35m'
CYAN = '\033[1;36m'
WHITE = '\033[1;37m'
RESET = '\033[0m'
DEBUG = True
LOG_TO_FILE = False
LOG_DIR = "fuzzlog"
LOG_PROJECT = None
LOG_DATE = None
PROJECT_LOGGER_MAP = {}
@staticmethod
def get_project_logger(log_project="default"):
if log_project in Colored.PROJECT_LOGGER_MAP:
return Colored.PROJECT_LOGGER_MAP[log_project]
logger = Colored(log_project)
Colored.PROJECT_LOGGER_MAP[log_project] = logger
return logger
def __init__(self, log_project="default"):
self.is_debug = True
self.is_log_file = False
self.log_project = log_project
self.log_date = time.strftime("%Y%m%d%H%M%S", time.localtime())
def start_log_file(self):
self.is_log_file = True
if not os.path.exists(Colored.LOG_DIR):
os.mkdir(Colored.LOG_DIR)
project_log_dir = self.get_fuzz_project_log_dir()
if not os.path.exists(project_log_dir):
os.mkdir(project_log_dir)
current_project_log_dir = self.get_fuzz_current_project_log_dir()
if not os.path.exists(current_project_log_dir):
os.mkdir(current_project_log_dir)
def get_fuzz_project_log_dir(self):
return os.path.join(Colored.LOG_DIR, self.log_project)
def get_fuzz_current_project_log_dir(self):
return os.path.join(Colored.LOG_DIR, self.log_project, self.log_date)
def get_fuzz_current_project_log_path(self):
return os.path.join(self.get_fuzz_current_project_log_dir(), "run.log")
def loghook(self, msg):
if self.is_log_file:
run_log = os.path.join(
self.get_fuzz_current_project_log_dir(),
"run.log"
)
with open(run_log, 'ab') as f:
f.write(msg+"\n")
def color_str(self, color, s, tag=None):
msg = ""
if tag:
msg = '{}{}{}{}'.format(
getattr(Colored, color),
tag,
s,
Colored.RESET
)
else:
msg = '{}{}{}'.format(
getattr(Colored, color),
s,
Colored.RESET
)
self.loghook(msg)
return msg
def red(self, s):
print(self.color_str('RED', s, "[ERROR] "))
def green(self, s):
if self.is_debug:
print(self.color_str('GREEN', s, "[INFO] "))
def yellow(self, s):
print(self.color_str('YELLOW', s, "[WARNING] "))
def blue(self, s):
return self.color_str('BLUE', s)
def fuchsia(self, s):
return self.color_str('FUCHSIA', s)
def cyan(s):
return self.color_str('CYAN', s)
def white(self, s):
print(self.color_str('WHITE', s))
def simple_print(self, s):
self.loghook(s)
print(s)
@staticmethod
def get_fuzz_log_dir():
return Colored.LOG_DIR
@staticmethod
def log_task_init(project):
Colored.LOG_TO_FILE = True
Colored.LOG_PROJECT = project
Colored.LOG_DATE = time.strftime("%Y%m%d%H%M%S", time.localtime())
if not os.path.exists(Colored.LOG_DIR):
os.mkdir(Colored.LOG_DIR)
project_log_dir = Colored.get_fuzz_project_log_dir()
if not os.path.exists(project_log_dir):
os.mkdir(project_log_dir)
current_project_log_dir = Colored.get_fuzz_current_project_log_dir()
if not os.path.exists(current_project_log_dir):
os.mkdir(current_project_log_dir)
#!/usr/bin/env python
# -*- coding:utf-8 -*-
#
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import re
class RunResult():
SUCCESS = 0
RUN_ENV_ERROR = -1
RUN_NO_DEVICE_ERROR = -2
RUN_CONFIG_FORMAT_ERROR = -3
RUN_CONFIG_FORMAT_NOCOLON_ERROR = -4
RUN_FUZZER_BIN_NOT_FOUND_ERROR = -5
RUN_CONNECT_ERROR = -6
RUN_EXEC_ERROR = -7
RUN_CONFIG_DICT_ERROR = -8
RUN_LINK_ERROR = -9
def __init__(self, code, data):
self.code = code
self.data = data
self.payload = {}
self.crash_info = {
"run_times": 0,
"log": "",
"project": "",
"speed": 0,
"summary": "No vulnerable",
"command_log": "",
"vulnerable": False,
"backtrace": "",
"cov": 0,
"libscov": {},
"report_progress": 0
}
def get_log(self):
return "code :{}, msg: {}".format(self.code, self.data)
@staticmethod
def filter_log(log_str):
ansi_escape = re.compile(r'''
\x1B
(?:
[@-Z\\-_]
|
\[
[0-?]*
[ -/]*
[@-~]
)
''', re.VERBOSE)
result = ansi_escape.sub('', log_str)
return result
def analysis(self, result, outdir):
pass
def write_analysis_result(self, analysis_ressult_path, html_format=True):
with open(analysis_ressult_path, "wb") as f:
if html_format:
f.write(RunResult.filter_log(render_detail(self.crash_info)))
else:
f.write(RunResult.filter_log(self.crash_info["backtrace"]))
if __name__ == "__main__":
cmd_log = ""
res_obj = RunResult(0, "OK")
res_obj.analysis(cmd_log, "../../../out/")
print(res_obj.crash_info)
#!/usr/bin/env python
# -*- coding:utf-8 -*-
#
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import os
import time
GN_ENTRY_TEMPLATE = """\
group("hydra_fuzz"){
testonly = true
if (use_libfuzzer) {
deps = ["//test/fuzzing_test/projects"]
}else{
deps = []
}
}
"""
PROJECT_GN_TEMPLATE = """\
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#####################hydra-fuzz###################
import("//build/config/features.gni")
import("//build/test.gni")
##############################fuzztest##########################################
ohos_fuzztest("") {
module_out_path = module_output_path
include_dirs = [
]
cflags = ["-g","-O0","-Wno-unused-variable","-fno-omit-frame-pointer"]
sources = [
"%(project_name)s.cpp",
]
}
###############################################################################
group("fuzztest") {
testonly = true
deps = []
deps += [
# deps file
":",
]
}
###############################################################################
"""
PROJECT_DEMO_TEMPLATE = """\
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "%(project_name)s.h"
#include <stddef.h>
#include <stdint.h>
const int FUZZ_DATA_LEN = 3
const int FUZZ_FST_DATA = 0
const int FUZZ_SND_DATA = 1
const int FUZZ_TRD_DATA = 2
const int FUZZ_FTH_DATA = 3
namespace OHOS {
bool DoSomethingInterestingWithMyAPI(const uint8_t* data, size_t size)
{
bool result = false;
if (size >= FUZZ_DATA_LEN) {
result = data[FUZZ_FST_DATA] == 'F' &&
data[FUZZ_SND_DATA] == 'U' &&
data[FUZZ_TRD_DATA] == 'Z' &&
data[FUZZ_FTH_DATA] == 'Z';
}
return result;
}
}
/* Fuzzer entry point */
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
/* Run your code on data */
OHOS::DoSomethingInterestingWithMyAPI(data, size);
return 0;
}
"""
PROJECT_HEADER_TEMPLATE = """\
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cstdint>
#include <unistd.h>
#include <climits>
#include <cstdio>
#include <cstdlib>
#include <fcntl.h>
#define FUZZ_PROJECT_NAME "%(project_name)s"
"""
PROJECT_XML_TEMPLATE = """\
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2021 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<fuzz_config>
<fuzztest>
<!-- maximum length of a test input -->
<max_len>1000</max_len>
<!-- maximum total time in seconds to run the fuzzer -->
<max_total_time>300</max_total_time>
<!-- memory usage limit in Mb -->
<rss_limit_mb>4096</rss_limit_mb>
</fuzztest>
</fuzz_config>
"""
REPORT_CSS_TEMPLATE = """
"""
def render_tbody(data):
res = ""
for row in data:
row_line = "<tr>"
for row_td in row:
row_line = row_line \
+ "\n<th scope=\"col\">{}</td>\n".format(row_td)
row_line = "%s %s " % (row_line, "</tr>")
res = res + row_line
return res
def render_common(data):
return REPORT_COMMON_HTML_TEMPLATE % data
def get_format_bt(backtrace):
new_backtrack = ""
line_tag = ["#0", "#1", "#2", "#3", "#4", "#5", "#6", "#7"]
block_file_list = [
"sanitizer_common_interceptors.inc",
"FuzzerDriver.cpp",
"FuzzerLoop.cpp",
"FuzzerMain.cpp",
"??"
]
tmp_flag = False
for line in backtrace.split("\n"):
tag_check = False
for tag in line_tag:
if line.strip().startswith(tag) == True \
and "in" in line and "exec/s" not in line:
tag_check = True
break
if tag_check:
block_flag = False
for block_line in block_file_list:
if block_line in line:
block_flag = True
break
if block_flag:
new_backtrack = " %s %s \n" % (new_backtrack, line)
else:
end_line = '<b target="view_frame" \
style="color: red; font-size:16px;\
" > %s </b>\n' % line
new_backtrack = " %s %s " % (new_backtrack, end_line)
else:
new_backtrack = " %s %s \n" % (new_backtrack, line)
return new_backtrack
\ No newline at end of file
#!/usr/bin/env python
# -*- coding:utf-8 -*-
#
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import os
import signal
import sys
import string
from templates import REPORT_SUMMARY_HTML_TEMPLATE
......@@ -22,6 +22,7 @@ from core.utils import scan_support_product
from core.config.config_manager import UserConfigManager
from core.build.select_targets import SelectTargets
from core.build.build_testcases import BuildTestcases
from core.command.gen import Gen
LOG = platform_logger("BuildManager")
......@@ -58,6 +59,16 @@ class BuildManager(object):
build_result = False
return build_result
@classmethod
def _compile_fuzz_test_case(cls, project_root_path, para):
build_result = BuildTestcases(
project_root_path).build_fuzz_testcases(para)
if build_result:
LOG.info("Test case compilation successed.")
else:
LOG.info("Test case compilation failed, please modify.")
return build_result
@classmethod
def _compile_all_test_cases(cls, project_root_path):
if BuildTestcases(project_root_path).build_all_testcases():
......@@ -100,10 +111,15 @@ class BuildManager(object):
"BUILD.gn")
self._make_gn_file(build_cfg_filepath, target_list)
build_result = self._compile_test_cases_by_target(
project_root_path,
para.productform,
"make_temp_test")
if "fuzztest" in para.testtype:
Gen().gen_fuzzer_list_file(target_list)
build_result = self._compile_fuzz_test_case(
project_root_path, para)
else:
build_result = self._compile_test_cases_by_target(
project_root_path,
para.productform,
"make_temp_test")
self._make_gn_file(build_cfg_filepath, [])
return build_result
......
......@@ -202,6 +202,18 @@ class BuildTestcases(object):
LOG.warning("Error: The %s is not exist" % BUILD_LITE)
return False
def build_fuzz_testcases(self, para):
self._delete_testcase_dir(para.productform)
helper_path = os.path.join("..", "libs", "fuzzlib", "fuzzer_helper.py")
command = [sys.executable, helper_path, 'make',
'make_temp_test', para.productform]
if subprocess.call(command, shell=False) == 0:
build_result = True
else:
build_result = False
self._merge_testcase_dir(para.productform)
return build_result
def build_testcases(self, productform, target):
command = []
if self.is_build_example:
......
......@@ -25,6 +25,7 @@ from core.constants import ToolCommandType
from xdevice import platform_logger
from xdevice import EnvironmentManager
from core.command.run import Run
from core.command.gen import Gen
from core.command.display import display_help_info
from core.command.display import display_show_info
from core.command.display import show_wizard_mode
......@@ -192,6 +193,20 @@ class Console(object):
default="",
help="Specify test resource"
)
parser.add_argument("-dp", "--dirpath",
action="store",
type=str,
dest="dirpath",
default="",
help="Specify fuzz test dirpath"
)
parser.add_argument("-fn", "--fuzzername",
action="store",
type=str,
dest="fuzzername",
default="",
help="Specify fuzzer name"
)
(options, unparsed) = parser.parse_known_args(para_list)
# Set default value
......@@ -229,6 +244,8 @@ class Console(object):
if "productform" in self.wizard_dic:
productform = self.wizard_dic["productform"]
self._process_command_show(para_list, productform)
elif command.startswith(ToolCommandType.TOOLCMD_KEY_GEN):
self._process_command_gen(command, options)
elif command.startswith(ToolCommandType.TOOLCMD_KEY_RUN):
if "productform" in self.wizard_dic:
options.productform = self.wizard_dic["productform"]
......@@ -260,6 +277,14 @@ class Console(object):
LOG.error("Wrong show command.")
return
@classmethod
def _process_command_gen(cls, command, options):
if command == ToolCommandType.TOOLCMD_KEY_GEN:
Gen().process_command_gen(options)
else:
LOG.error("Wrong gen command.")
return
@classmethod
def _process_command_run(cls, command, options):
if command == ToolCommandType.TOOLCMD_KEY_RUN:
......
#!/usr/bin/env python3
# coding=utf-8
#
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import os
import sys
import subprocess
from xdevice import platform_logger
LOG = platform_logger("Gen")
class Gen(object):
def process_command_gen(self, options):
if (len(options.testtype) != 1) or (options.dirpath == "") or \
(options.fuzzername == ""):
LOG.error(
"GEN need para -t(testtype) -fz(fuzzername) -dp(dirpath)")
return
if "FUZZ" in options.testtype:
self.fuzz_dir_generation(options)
else:
LOG.error("GEN is not support %s." % options.testtype)
def gen_fuzzer_list_file(self, fuzzer_list):
filepath = os.path.join(sys.source_code_root_path, "test",
"developertest", "libs", "fuzzlib", "fuzzer_list.txt")
LOG.info("The fuzzer list file path: %s" % filepath)
with open(filepath, "w") as gn_file:
gn_file.truncate(0)
if fuzzer_list:
for target in fuzzer_list:
if target:
gn_file.write("\"%s\",\n" % target)
@classmethod
def fuzz_dir_generation(cls, options):
helper_path = os.path.join("..", "libs", "fuzzlib", "fuzzer_helper.py")
fuzz_path = os.path.join(sys.source_code_root_path, options.dirpath)
LOG.info("fuzz_path = %s" % fuzz_path)
if not os.path.exists(fuzz_path):
LOG.error("%s is not exist." % fuzz_path)
return
LOG.info("%s exist." % fuzz_path)
command = [sys.executable, helper_path, 'generate',
options.fuzzername, fuzz_path]
LOG.info("command %s" % command)
subprocess.call(command, shell=False)
\ No newline at end of file
......@@ -283,3 +283,27 @@ class BuildConfigManager(object):
def get_build_path(self):
return self.filepath
class FuzzerConfigManager(object):
def __init__(self, config_path=""):
if config_path == "":
self.filepath = self.filepath = os.path.abspath(os.path.join(
CONFIG_PATH, ConfigFileConst.FUZZCONFIG_FILEPATH))
else:
self.filepath = config_path
def get_fuzzer_config(self, target_name):
config_list = []
try:
LOG.info("fuzzer config file :%s" % self.filepath)
if os.path.exists(self.filepath):
tree = ET.parse(self.filepath)
root = tree.getroot()
node = root.find(target_name)
LOG.info("before for")
for sub in node:
if sub.text is not None:
config_list.append(sub.text)
except ET.ParseError as xml_exception:
LOG.error(("Parse %s fail!" % self.filepath) + xml_exception.args)
return config_list
......@@ -46,6 +46,7 @@ class ToolCommandType(object):
TOOLCMD_KEY_RUN = "run"
TOOLCMD_KEY_QUIT = "quit"
TOOLCMD_KEY_LIST = "list"
TOOLCMD_KEY_GEN = "gen"
@property
def run_command(self):
......@@ -64,6 +65,7 @@ class ConfigFileConst(object):
RESOURCECONFIG_FILEPATH = "harmony_test.xml"
CASE_RESOURCE_FILEPATH = "ohos_test.xml"
SCENECONFIG_FILEPATH = "scene_config.xml"
FUZZCONFIG_FILEPATH = "fuzz_config.xml"
@property
def framework_config_file(self):
......
......@@ -17,11 +17,11 @@
#
import os
import re
import time
import platform
from dataclasses import dataclass
from xdevice import DeviceTestType
from xdevice import DeviceLabelType
from xdevice import ExecuteTerminate
......@@ -31,7 +31,9 @@ from xdevice import IDriver
from xdevice import platform_logger
from xdevice import Plugin
from core.utils import get_decode
from core.utils import get_fuzzer_path
from core.config.resource_manager import ResourceManager
from core.config.config_manager import FuzzerConfigManager
__all__ = [
......@@ -186,7 +188,68 @@ def _sleep_according_to_result(result):
if result:
time.sleep(1)
def _create_fuzz_crash_file(filepath, filename):
if not os.path.exists(filepath):
with open(filepath, "w", encoding='utf-8') as file_desc:
time_stamp = time.strftime("%Y-%m-%d %H:%M:%S",
time.localtime())
file_desc.write('<?xml version="1.0" encoding="UTF-8"?>\n')
file_desc.write(
'<testsuites disabled="0" name="AllTests" '
'time="300" timestamp="%s" errors="0" '
'failures="1" tests="1">\n' % time_stamp)
file_desc.write(
' <testsuite disabled="0" name="%s" time="300" '
'errors="0" failures="1" tests="1">\n' % filename)
file_desc.write(
' <testcase name="%s" time="300" classname="%s" '
'status="run">\n' % (filename, filename))
file_desc.write(
' <failure type="" '
'message="Fuzzer crash. See ERROR in log file">\n')
file_desc.write(' </failure>\n')
file_desc.write(' </testcase>\n')
file_desc.write(' </testsuite>\n')
file_desc.write('</testsuites>\n')
return
def _create_fuzz_pass_file(filepath, filename):
if not os.path.exists(filepath):
with open(filepath, "w", encoding='utf-8') as file_desc:
time_stamp = time.strftime("%Y-%m-%d %H:%M:%S",
time.localtime())
file_desc.write('<?xml version="1.0" encoding="UTF-8"?>\n')
file_desc.write(
'<testsuites disabled="0" name="AllTests" '
'time="300" timestamp="%s" errors="0" '
'failures="0" tests="1">\n' % time_stamp)
file_desc.write(
' <testsuite disabled="0" name="%s" time="300" '
'errors="0" failures="0" tests="1">\n' % filename)
file_desc.write(
' <testcase name="%s" time="300" classname="%s" '
'status="run"/>\n' % (filename, filename))
file_desc.write(' </testsuite>\n')
file_desc.write('</testsuites>\n')
return
def _create_fuzz_result_file(filepath, filename, error_message):
error_message = str(error_message)
error_message = error_message.replace("\"", "")
error_message = error_message.replace("<", "")
error_message = error_message.replace(">", "")
error_message = error_message.replace("&", "")
if "AddressSanitizer" in error_message:
LOG.error("FUZZ TEST CRASH")
_create_fuzz_crash_file(filepath, filename)
elif re.search(r'Done (\b\d+\b) runs in (\b\d+\b) second',
error_message, re.M) is not None:
LOG.info("FUZZ TEST PASS")
_create_fuzz_pass_file(filepath, filename)
else:
LOG.error("FUZZ TEST UNAVAILABLE")
_create_empty_result_file(filepath, filename, error_message)
return
##############################################################################
##############################################################################
......@@ -209,6 +272,11 @@ class ResultManager(object):
def get_test_results(self, error_message=""):
# Get test result files
filepath = self.obtain_test_result_file()
if "fuzztest" == self.config.testtype[0]:
LOG.info("create fuzz test report")
_create_fuzz_result_file(filepath, self.testsuite_name,
error_message)
return filepath
if not os.path.exists(filepath):
_create_empty_result_file(filepath, self.testsuite_name,
error_message)
......@@ -394,6 +462,10 @@ class CppTestDriver(IDriver):
"rm -rf %s" % self.config.target_test_path)
self.config.device.execute_shell_command(
"mkdir -p %s" % self.config.target_test_path)
if "fuzztest" == self.config.testtype[0]:
self.config.device.execute_shell_command(
"mkdir -p %s" % os.path.join(self.config.target_test_path,
"corpus"))
def _run_gtest(self, suite_file):
from xdevice import Variables
......@@ -407,6 +479,7 @@ class CppTestDriver(IDriver):
# push testsuite file
self.config.device.push_file(suite_file, self.config.target_test_path)
self._push_corpus_if_exist(filename)
# push resource files
resource_manager = ResourceManager()
......@@ -453,6 +526,12 @@ class CppTestDriver(IDriver):
resource_dir,
self.config.device)
def _push_corpus_if_exist(self, filename):
if "fuzztest" == self.config.testtype[0]:
corpus_path = os.path.join(get_fuzzer_path(filename), "corpus")
self.config.device.push_file(corpus_path,
os.path.join(self.config.target_test_path, "corpus"))
@staticmethod
def _get_test_para(testcase,
testlevel,
......@@ -472,6 +551,14 @@ class CppTestDriver(IDriver):
test_para = "%s=%s" % (GTestConst.exec_para_level, level_para)
else:
test_para = ""
if "fuzztest" == testtype[0]:
cfg_list = FuzzerConfigManager(os.path.join(get_fuzzer_path(
filename), "project.xml")).get_fuzzer_config("fuzztest")
LOG.info("config list :%s" % str(cfg_list))
test_para += "corpus -max_len=" + cfg_list[0] + \
" -max_total_time=" + cfg_list[1] + \
" -rss_limit_mb=" + cfg_list[2]
return test_para
......
......@@ -152,3 +152,22 @@ def get_decode(stream):
except (ValueError, AttributeError, TypeError):
ret = str(stream)
return ret
def parse_fuzzer_info():
path_list = []
bin_list = []
list_path = os.path.join(sys.source_code_root_path, "test",
"developertest", "libs", "fuzzlib", "fuzzer_list.txt")
with open(list_path, 'r') as list_file:
for line in list_file.readlines():
striped_str = line.strip()
path_list.append(striped_str.split(":")[0][3:])
bin_list.append(striped_str.split(":")[1].split("(")[0])
return path_list, bin_list
def get_fuzzer_path(filename):
path_list, bin_list = parse_fuzzer_info()
for i, name in enumerate(bin_list):
if name == filename:
return os.path.join(sys.source_code_root_path, path_list[i])
return ""
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册