diff --git a/projects/golang/Dockerfile b/projects/golang/Dockerfile index 9083d8bdc..5769bfd7b 100644 --- a/projects/golang/Dockerfile +++ b/projects/golang/Dockerfile @@ -43,6 +43,7 @@ COPY build.sh text_fuzzer.go \ filepath_fuzzer.go \ strings_fuzzer.go \ multipart_fuzzer.go \ + encoding_fuzzer.go \ glob_fuzzer.options $SRC/ WORKDIR $SRC/golang diff --git a/projects/golang/build.sh b/projects/golang/build.sh index b402de380..7e013ab61 100755 --- a/projects/golang/build.sh +++ b/projects/golang/build.sh @@ -47,12 +47,15 @@ function setup_golang_fuzzers() { cp $SRC/multipart_fuzzer.go $SRC/golang/multipart/main.go + mkdir $SRC/golang/encoding && cp $SRC/encoding_fuzzer.go $SRC/golang/encoding/ + go mod init "github.com/dvyukov/go-fuzz-corpus" } function compile_fuzzers() { # version is used as suffix for the binaries version=$1 + compile_go_fuzzer $FUZZ_ROOT/encoding FuzzEncoding fuzz_encoding$version compile_go_fuzzer $FUZZ_ROOT/strings FuzzStringsSplit fuzz_strings_split$version compile_go_fuzzer $FUZZ_ROOT/fp FuzzFpGlob glob_fuzzer$version compile_go_fuzzer $FUZZ_ROOT/crypto/x509 FuzzParseCert fuzz_parse_cert$version diff --git a/projects/golang/encoding_fuzzer.go b/projects/golang/encoding_fuzzer.go new file mode 100644 index 000000000..2f2c01656 --- /dev/null +++ b/projects/golang/encoding_fuzzer.go @@ -0,0 +1,71 @@ +package encoding + +import ( + "bytes" + "encoding/base32" + "encoding/base64" + "encoding/gob" + "encoding/json" + "encoding/xml" + "runtime" + fuzz "github.com/AdaLogics/go-fuzz-headers" +) + +func FuzzEncoding(data []byte) int { + f := fuzz.NewConsumer(data) + decType, err := f.GetInt() + if err != nil { + return 0 + } + b1, err := f.GetBytes() + if err != nil { + return 0 + } + b2, err := f.GetBytes() + if err != nil { + return 0 + } + defer func() { + if r := recover(); r != nil { + } + runtime.GC() + }() + switch decType%5 { + case 0: + e, err := f.GetString() + if err != nil || len(e) != 32 { + return 0 + } + enc := base32.NewEncoding(e) + d := base32.NewDecoder(enc, bytes.NewReader(b1)) + _, _ = d.Read(b2) + return 1 + case 1: + e, err := f.GetString() + if err != nil || len(e) != 64 { + return 0 + } + for i := 0; i < len(e); i++ { + if e[i] == '\n' || e[i] == '\r' { + return 0 + } + } + enc := base64.NewEncoding(e) + d := base64.NewDecoder(enc, bytes.NewReader(b1)) + _, _ = d.Read(b2) + return 1 + case 2: + d := gob.NewDecoder(bytes.NewReader(b1)) + _ = d.Decode(b2) + return 1 + case 3: + d := json.NewDecoder(bytes.NewReader(b1)) + _ = d.Decode(b2) + return 1 + case 4: + d := xml.NewDecoder(bytes.NewReader(b1)) + _, _ = d.Token() + return 1 + } + return 1 +}