Skip to content

Commit

Permalink
initial commit for enhancing fuzz tests (#2745)
Browse files Browse the repository at this point in the history
* initial commit for enhancing fuzz tests

Signed-off-by: Sepehrdad Sh <[email protected]>

* fix dockerfile, add retry for fuzzserver and add dictionary for fuzzserver

Signed-off-by: Sepehrdad Sh <[email protected]>

* fix makefile cleanup, fix FuzzServer with Fuzz_FORKS

Signed-off-by: Sepehrdad Sh <[email protected]>

* FuzzServer: move init to func init(), add try delay

Signed-off-by: Sepehrdad Sh <[email protected]>

* FuzzParseIPCIDRs: add new target

Signed-off-by: Sepehrdad Sh <[email protected]>

* FuzzServer: tcp6 -> tcp as tcp6 is very slow, func init -> init var as using func init will affect other fuzz targets.

Signed-off-by: Sepehrdad Sh <[email protected]>

* gosigfuzz: add the patch to fix libfuzzer signal handling, imported from oss-fuzz.

Signed-off-by: Sepehrdad Sh <[email protected]>

* Dockerfile: fix build, Makefile: remove msan as its broken and add an option to compile without sanitizers.

Signed-off-by: Sepehrdad Sh <[email protected]>

---------

Signed-off-by: Sepehrdad Sh <[email protected]>
  • Loading branch information
sepehrdaddev authored Nov 28, 2023
1 parent 19f60cb commit 6460a2f
Show file tree
Hide file tree
Showing 16 changed files with 750 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ _test_plugins_fail/%.so: _test_plugins_fail/%.go

.PHONY: fuzz
fuzz: ## run all fuzz tests
for p in $(PACKAGES); do go test -run=NONE -fuzz=Fuzz -fuzztime 30s $$p; done
$(MAKE) -C fuzz $(MAKECMDGOALS)

.PHONY: lint
lint: build staticcheck ## run all linters
Expand Down
21 changes: 21 additions & 0 deletions fuzz/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
FROM amazonlinux:2023

WORKDIR /workspace

ENV PATH="/root/go/bin:$PATH"

COPY . .

RUN dnf install -q -y make clang golang && \
update-alternatives --install /usr/bin/cc cc /usr/bin/clang 20 && \
go install github.com/mdempsky/go114-fuzz-build@latest && \
go mod init fuzz && \
go mod tidy && \
make -s -j $(nproc) && \
dnf autoremove -q -y && \
dnf clean all -q && \
go clean -cache -testcache -modcache -fuzzcache

ENTRYPOINT [ "/usr/bin/make", "fuzz" ]

CMD ["FUZZ_TARGETS=FuzzParseEskip"]
64 changes: 64 additions & 0 deletions fuzz/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
MKDIR = mkdir -p
GO_FUZZ_BUILD ?= go114-fuzz-build

PREFIX ?= $(CURDIR)
ARTIFACTS_PATH = $(PREFIX)/artifacts
DICTIONARY_PATH = $(PREFIX)/dictionaries
CORPUS_PATH = $(PREFIX)/corpus
FUZZ_TARGETS_PATH = $(PREFIX)/fuzz_targets

FUZZ_TARGETS ?= FuzzParseCIDRs FuzzParseEskip FuzzParseFilters \
FuzzParseIngressV1JSON FuzzParseIPCIDRs \
FuzzParseJwt FuzzParsePredicates \
FuzzParseRouteGroupsJSON FuzzServer

FUZZ_SANITIZER ?= address
FUZZ_FORKS ?= 2
FUZZ_MAX_TOTAL_TIME ?= 600
FUZZ_RUNS ?= -1
FUZZER_ARGS ?= -artifact_prefix=$(ARTIFACTS_PATH) \
-rss_limit_mb=2560 -timeout=25 \
-max_total_time=$(FUZZ_MAX_TOTAL_TIME) \
-len_control=0 -detect_leaks=0 -max_len=4096 \
-fork=$(FUZZ_FORKS) -runs=$(FUZZ_RUNS)

ifeq ($(FUZZ_SANITIZER), address)
FUZZ_BUILD_ARGS = -fsanitize=fuzzer -fsanitize=address -fsanitize-address-use-after-scope
else ifeq ($(FUZZ_SANITIZER), undefined)
FUZZ_BUILD_ARGS = -fsanitize=fuzzer -fsanitize=array-bounds,bool,builtin,enum,float-divide-by-zero,function,integer-divide-by-zero,null,object-size,return,returns-nonnull-attribute,shift,signed-integer-overflow,unsigned-integer-overflow,unreachable,vla-bound,vptr -fno-sanitize-recover=array-bounds,bool,builtin,enum,float-divide-by-zero,function,integer-divide-by-zero,null,object-size,return,returns-nonnull-attribute,shift,signed-integer-overflow,unreachable,vla-bound,vptr
else ifeq ($(FUZZ_SANITIZER), none)
FUZZ_BUILD_ARGS = -fsanitize=fuzzer
else
$(error $(FUZZ_SANITIZER) is invalid sanitizer, available options are address, undefined, none)
endif

export ASAN_OPTIONS = alloc_dealloc_mismatch=0:allocator_may_return_null=1:allocator_release_to_os_interval_ms=500:check_malloc_usable_size=0:detect_container_overflow=1:detect_odr_violation=0:detect_leaks=1:detect_stack_use_after_return=1:fast_unwind_on_fatal=0:handle_abort=1:handle_segv=1:handle_sigill=1:max_uar_stack_size_log=16:print_scariness=1:quarantine_size_mb=10:strict_memcmp=1:symbolize=1:use_sigaltstack=1:dedup_token_length=3
export UBSAN_OPTIONS = print_stacktrace=1:print_summary=1:silence_unsigned_overflow=1:symbolize=1:dedup_token_length=3

.PHONY: help all fuzz clean
default: all

help: ## display this help
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)

all: $(FUZZ_TARGETS:=.out) ## build all fuzz binaries

%.a:
$(GO_FUZZ_BUILD) -func $(@:.a=) -o $@ $(FUZZ_TARGETS_PATH)

gosigfuzz/gosigfuzz.o:
$(CC) -c $(@:.o=.c) -o $@

%.out: %.a gosigfuzz/gosigfuzz.o
$(CC) $(FUZZ_BUILD_ARGS) -lresolv $^ -o $@

fuzz: $(FUZZ_TARGETS:=.out) ## run all fuzz tests
for TARGET in $(FUZZ_TARGETS); do \
$(MKDIR) $(CORPUS_PATH)/$$TARGET $(ARTIFACTS_PATH); \
ARGS="$(FUZZER_ARGS)"; \
[ -f "$(DICTIONARY_PATH)/$$TARGET.dict" ] && ARGS="$$ARGS -dict=$(DICTIONARY_PATH)/$$TARGET.dict"; \
$(PREFIX)/$$TARGET.out $$ARGS $(CORPUS_PATH)/$$TARGET; \
done

clean: ## clean temporary files and directories
$(RM) $(PREFIX)/*.out $(PREFIX)/*.a $(PREFIX)/*.h $(PREFIX)/main.*.go gosigfuzz/gosigfuzz.o
3 changes: 3 additions & 0 deletions fuzz/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Fuzzing

This directory contains a set of dictionaries and fuzz targets along with other tooling to fuzz skipper.
188 changes: 188 additions & 0 deletions fuzz/dictionaries/FuzzParseEskip.dict
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
"&&"
"*"
"->"
")"
":"
","
"("
";"
"<shunt>"
"<loopback>"
"<dynamic>"
"<"
">"
"backendIsProxy"
"modRequestHeader"
"setRequestHeader"
"appendRequestHeader"
"dropRequestHeader"
"modResponseHeader"
"setResponseHeader"
"appendResponseHeader"
"dropResponseHeader"
"setContextRequestHeader"
"appendContextRequestHeader"
"setContextResponseHeader"
"appendContextResponseHeader"
"copyRequestHeader"
"copyResponseHeader"
"modPath"
"setPath"
"redirectTo"
"redirectToLower"
"static"
"stripQuery"
"preserveHost"
"status"
"compress"
"decompress"
"setQuery"
"dropQuery"
"inlineContent"
"inlineContentIfStatus"
"flowId"
"xforward"
"xforwardFirst"
"randomContent"
"repeatContent"
"repeatContentHex"
"wrapContent"
"wrapContentHex"
"backendTimeout"
"readTimeout"
"writeTimeout"
"blockContent"
"blockContentHex"
"latency"
"bandwidth"
"chunks"
"backendLatency"
"backendBandwidth"
"backendChunks"
"absorb"
"absorbSilent"
"uniformRequestLatency"
"uniformResponseLatency"
"normalRequestLatency"
"normalResponseLatency"
"histogramRequestLatency"
"histogramResponseLatency"
"logHeader"
"tee"
"teenf"
"teeLoopback"
"sed"
"sedDelim"
"sedRequest"
"sedRequestDelim"
"basicAuth"
"webhook"
"oauthTokeninfoAnyScope"
"oauthTokeninfoAllScope"
"oauthTokeninfoAnyKV"
"oauthTokeninfoAllKV"
"oauthTokenintrospectionAnyClaims"
"oauthTokenintrospectionAllClaims"
"oauthTokenintrospectionAnyKV"
"oauthTokenintrospectionAllKV"
"secureOauthTokenintrospectionAnyClaims"
"secureOauthTokenintrospectionAllClaims"
"secureOauthTokenintrospectionAnyKV"
"secureOauthTokenintrospectionAllKV"
"forwardToken"
"forwardTokenField"
"oauthGrant"
"grantCallback"
"grantLogout"
"grantClaimsQuery"
"jwtValidation"
"oauthOidcUserInfo"
"oauthOidcAnyClaims"
"oauthOidcAllClaims"
"oidcClaimsQuery"
"dropRequestCookie"
"dropResponseCookie"
"requestCookie"
"responseCookie"
"jsCookie"
"consecutiveBreaker"
"rateBreaker"
"disableBreaker"
"admissionControl"
"clientRatelimit"
"ratelimit"
"clusterClientRatelimit"
"clusterRatelimit"
"clusterLeakyBucketRatelimit"
"backendRatelimit"
"ratelimitFailClosed"
"lua"
"corsOrigin"
"headerToQuery"
"queryToHeader"
"disableAccessLog"
"enableAccessLog"
"auditLog"
"unverifiedAuditLog"
"setDynamicBackendHostFromHeader"
"setDynamicBackendSchemeFromHeader"
"setDynamicBackendUrlFromHeader"
"setDynamicBackendHost"
"setDynamicBackendScheme"
"setDynamicBackendUrl"
"apiUsageMonitoring"
"fifo"
"lifo"
"lifoGroup"
"rfcPath"
"rfcHost"
"bearerinjector"
"tracingBaggageToTag"
"stateBagToTag"
"tracingTag"
"tracingTagFromResponse"
"tracingSpanName"
"originMarker"
"fadeIn"
"endpointCreated"
"consistentHashKey"
"consistentHashBalanceFactor"
"opaAuthorizeRequest"
"opaServeResponse"
"healthcheck"
"setFastCgiFilename"
"disableRatelimit"
"unknownRatelimit"
"Path"
"PathSubtree"
"PathRegexp"
"Host"
"HostAny"
"ForwardedHost"
"ForwardedProtocol"
"Weight"
"True"
"False"
"Shutdown"
"Method"
"Methods"
"Header"
"HeaderRegexp"
"Cookie"
"JWTPayloadAnyKV"
"JWTPayloadAllKV"
"JWTPayloadAnyKVRegexp"
"JWTPayloadAllKVRegexp"
"HeaderSHA256"
"After"
"Before"
"Between"
"Cron"
"QueryParam"
"Source"
"SourceFromLast"
"ClientIP"
"Tee"
"Traffic"
"TrafficSegment"
"ContentLengthBetween"
Loading

0 comments on commit 6460a2f

Please sign in to comment.