Стенд знакомит с coverage-guided фаззингом Go-кода на примере функции gjson.Parse.
- команды сборки и запуска выполняются из корня
- команды фаззинга выполняются внутри контейнера из /go/src/gjson-1.18.0
docker build --tag=gjson_workshop_img .--tagзадаёт имя.передаёт текущий каталог как точку сборки
docker run -it -v "$(pwd)/artifacts:/home/fuzz/artifacts:ro" --name=gjson_fuzz gjson_workshop_img-itзапускает контейнер с терминалом--nameзадаёт имя контейнера-vподключает локальный каталогartifactsк/home/fuzz/artifactsвнутри контейнера:roмонтирует каталог только для чтения
cd /go/src/gjson-1.18.0
git apply /home/fuzz/artifacts/gjson.patch
mkdir -p testdata/fuzz/FuzzParseJSON
cp /home/fuzz/artifacts/corpus/* testdata/fuzz/FuzzParseJSON/git apply добавляет fuzz-функцию в исходники gjson
testdata/fuzz/FuzzParseJSON — каталог seed корпуса. Фаззер берёт из него стартовые тесткейсы для FuzzParseJSON
Патч добавляет:
func FuzzParseJSON(f *testing.F) {
f.Fuzz(func(t *testing.T, orig string) {
Parse(orig)
})
}f *testing.F— объект фаззераf.Fuzz(...)задаёт тестирующую функциюorig string— вход, который генерирует фаззерParse(orig)— целевая функция
Основные показатели строки статистики:
| Показатель | Значение |
|---|---|
elapsed |
время работы фаззера |
execs |
число выполнений fuzz-target |
new interesting |
новые входы, которые дали покрытие |
go test -fuzz=Fuzz -run=FuzzParseJSON-fuzz=Fuzzзапускает фаззинг тестов, имя которых начинается сFuzz-run=FuzzParseJSONвыбирает конкретный fuzz-тест
Остановка: Ctrl+C. Найденные интересные входы сохраняются в кэше Go
Копируем найденные входы из кэша обратно в корпус и генерим HTML-отчёт:
cp $(go env GOCACHE)/fuzz/$(go list)/FuzzParseJSON/* testdata/fuzz/FuzzParseJSON
go test -coverprofile=coverage.out -run=FuzzParseJSON -v
go tool cover -html=coverage.out -o ./coverage.htmlgo env GOCACHE— каталог кэша Gogo list— путь пакета-coverprofileпишет профиль покрытия в файл-run=FuzzParseJSONпрогоняет корпус без мутациgo tool cover -htmlгенерит HTML-отчёт
На хосте:
docker cp gjson_fuzz:/go/src/gjson-1.18.0/coverage.html .Отчет появится в текущкй папке