用libfuzzer模糊Go应用程序:错误的覆盖率

时间:2018-12-04 18:15:56

标签: go shared-libraries llvm fuzzing libfuzzer

我正在写论文,非常感谢您对当前设置的一些投入。 我想用libfuzzer模糊目标Go应用程序,因此执行了以下操作:

我写了一个主程序包,调用了要测试的go函数。 代码:

package main
import "C"
import "$PACKAGE"
func main(){}
//export Fuzz
func Fuzz(data []byte){
 $PACKAGE.Fuzz(data) //actual Fuzzing function, which instruments the function under test  
}

llvm-go必须有一个主程序包才能将应用程序实际构建为共享库。我在这里有双重抽象的原因是,我希望我的构建管道与go-fuzz兼容,后者使用“ Fuzz”函数名称作为模糊输入点。通过我的设置,我可以简单地包装使用libfuzzer所需的代码。

然后我用llvm-go编译应用程序。

现在,我有两种方法可以检测Go共享库:动态加载它或将其静态链接到我的二进制文件中。我将使用静态链接代码解释我的问题。为此,我编写了一些模糊的存根,用于检测Go共享库。

// fuzz_target.cc
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <dlfcn.h>
#include "golang-app.h"

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
 void *handle;
 char *error; 
 GoSlice data = {(void*)Data, static_cast<long long>(Size), static_cast<long long>(Size)};
 Fuzz(data);
 return 0; // Non-zero return values are reserved for future use.
}

然后使用以下代码进行编译:

clang -g -O1 -fsanitize=fuzzer,address -o fuzz fuzzing-entry_static.cc ../golang-app.so

现在,当我运行代码时,我看到两个问题:

master@thesis:~/go-libfuzz$ ./fuzz-static ./corpus/ -timeout=12
INFO: Seed: 2260122321
INFO: Loaded 1 modules   (1 inline 8-bit counters): 1 [0x787f60, 0x787f61),
INFO: Loaded 1 PC tables (1 PCs): 1 [0x565bd0,0x565be0),
INFO:       11 files found in ./corpus/
INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 18061 bytes
INFO: seed corpus: files: 11 min: 450b max: 18061b total: 76971b rss: 51Mb
#12     INITED cov: 1 ft: 1 corp: 1/450b exec/s: 0 rss: 53Mb
#13     REDUCE cov: 1 ft: 1 corp: 1/282b exec/s: 0 rss: 53Mb L: 282/282 MS: 1 EraseBytes-
[...]
#193    REDUCE cov: 1 ft: 1 corp: 1/1b exec/s: 0 rss: 56Mb L: 1/1 MS: 1 EraseBytes-
#65536  pulse  cov: 1 ft: 1 corp: 1/1b exec/s: 21845 rss: 63Mb
#131072 pulse  cov: 1 ft: 1 corp: 1/1b exec/s: 26214 rss: 68Mb
#262144 pulse  cov: 1 ft: 1 corp: 1/1b exec/s: 26214 rss: 79Mb
#524288 pulse  cov: 1 ft: 1 corp: 1/1b exec/s: 27594 rss: 100Mb
#1048576        pulse  cov: 1 ft: 1 corp: 1/1b exec/s: 27594 rss: 142Mb
#2097152        pulse  cov: 1 ft: 1 corp: 1/1b exec/s: 27962 rss: 226Mb

覆盖范围和功能似乎并没有增加,并且每次运行都增加了内存需求。通过将一个环境变量添加到模糊器执行中,我能够通过另一个SO发布来解决内存增加的问题。 ASAN_OPTIONS=quarantine_size_mb=20 ./fuzz-target -timeout=12

但是,可能的主要问题是,实际目标被“埋没”在两个抽象级别下: LLVMFuzzerTestOneInput --calls->通过main.go共享Go库,该库包含导出的Fuzz函数(通过CGo公开),该函数-call-> Fuzzing函数--calls->目标函数。 但是请注意,这些功能中的每一个功能都只是将数据直接移交给下一层而不进行更改。 我可以采取什么步骤来确保其正常工作?我在做错什么吗?

0 个答案:

没有答案