首页 > 解决方案 > 使用 libfuzzer 对 Go 应用程序进行模糊测试:错误的覆盖范围

问题描述

我正在写我的论文,非常感谢对我当前设置的一些输入。我想用 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 共享库的 fuzzing 存根。

// 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 公开),其中 --calls --> Fuzzing 函数 --calls--> 目标函数。但是请注意,这些函数中的每一个都只是将数据直接移交给下一层而不进行更改。我可以采取哪些步骤来确保它正常工作?难道我做错了什么?

标签: goshared-librariesllvmfuzzinglibfuzzer

解决方案


推荐阅读