Fuzzing приложение Go с libfuzzer: неправильное освещение - PullRequest
0 голосов
/ 04 декабря 2018

Я пишу свою диссертацию и буду очень признателен за мой вклад в мою текущую настройку.Я хочу запитать целевое приложение Go с помощью libfuzzer и поэтому сделал следующее:

Я написал основной пакет, который вызывает функцию 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 -> разделяемая библиотека Go через main.go, которая содержит экспортированную функцию Fuzz(выставляется через CGo) который --calls -> Fuzzing function --calls -> target function.Обратите внимание, однако, что каждая из этих функций просто передает данные непосредственно на следующий уровень без внесения изменений.Какие шаги я могу сделать, чтобы убедиться, что это работает правильно?Я что-то не так делаю?

...