From 7039ed44e3f11f6e593e82f9dc8074f51bc99944 Mon Sep 17 00:00:00 2001 From: Jawad Zaheer Date: Wed, 19 Jul 2023 11:03:44 +0000 Subject: [PATCH] Added fuzzing targets for capm3. --- test/fuzz/README.md | 51 +++++++++++++++++++ .../fuzz/metal3cluster_manager_test_fuzzer.go | 31 +++++++++++ test/go.mod | 2 + test/go.sum | 4 ++ 4 files changed, 88 insertions(+) create mode 100644 test/fuzz/README.md create mode 100644 test/fuzz/metal3cluster_manager_test_fuzzer.go diff --git a/test/fuzz/README.md b/test/fuzz/README.md new file mode 100644 index 0000000000..555a87dfd3 --- /dev/null +++ b/test/fuzz/README.md @@ -0,0 +1,51 @@ +# Fuzzing + + Fuzzing or fuzz testing is an automated software testing technique that + involves providing invalid, unexpected, or random data as inputs to a + computer program. A fuzzing target is defined for running the tests. + These targets are defined in the test/fuzz directory and run using + the instructions given below: + +- Install the package from + using go get command. This is the link for the fuzzing tool that uses + libfuzzer for its implementation purposes. I set it up and made a sample + function to run the fuzzing tests. In these steps following are the important steps + + a.  Run below command to build the file for the function by giving its location. + + ```bash + mkdir output + cd output + go114-fuzz-build -o FuzzTestImageValidate.a + -func FuzzTestImageValidate ../test/fuzz/ + ``` + + b. Run below command to make C binary files for the same function. + + ``` + clang -o FuzzTestImageValidate FuzzTestImageValidate.a + -fsanitize=fuzzer + ``` + + c. Run the fuzzer as below + + ``` + /FuzzTestImageValidate + ``` + +- Execution: Here is an example for execution of some test outputs: + + ```bash + ./FuzzTestImageValidate + INFO: Running with entropic power schedule (0xFF, 100). + INFO: Seed: 376384327 + INFO: 267805 Extra Counters + INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes + INFO: A corpus is not provided, starting from an empty corpus + #2 INITED ft: 35 corp: 1/1b exec/s: 0 rss: 51Mb + ``` + + Here first line contains the byte array provided by libfuzzer to the + function we then typecast it to our struct of IPPool using JSON. + Unmarshal and then run the function. It keeps on running + until it finds a bug. diff --git a/test/fuzz/metal3cluster_manager_test_fuzzer.go b/test/fuzz/metal3cluster_manager_test_fuzzer.go new file mode 100644 index 0000000000..e09b8b8492 --- /dev/null +++ b/test/fuzz/metal3cluster_manager_test_fuzzer.go @@ -0,0 +1,31 @@ +package fuzz_test + +import ( + fuzz "github.com/AdaLogics/go-fuzz-headers" + infrav1 "github.com/metal3-io/cluster-api-provider-metal3/api/v1beta1" + "k8s.io/apimachinery/pkg/util/validation/field" +) + +type ImageValidate struct { + Image infrav1.Image + ErrorExpected bool + Name string +} + +func FuzzTestImageValidate(data []byte) int { + f := fuzz.NewConsumer(data) + tc := &ImageValidate{} + err := f.GenerateStruct(tc) + if err != nil { + return 0 + } + errs := tc.Image.Validate(*field.NewPath("Spec", "Image")) + if tc.ErrorExpected && errs == nil { + return 0 + } + if !tc.ErrorExpected && errs != nil { + return 0 + } + + return 1 +} diff --git a/test/go.mod b/test/go.mod index 9d1bdb1e8a..3eadc7d05d 100644 --- a/test/go.mod +++ b/test/go.mod @@ -28,6 +28,7 @@ replace sigs.k8s.io/cluster-api/test => sigs.k8s.io/cluster-api/test v1.5.0 replace github.com/metal3-io/cluster-api-provider-metal3/api => ./../api require ( + github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 github.com/BurntSushi/toml v1.0.0 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect @@ -44,6 +45,7 @@ require ( github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/coredns/caddy v1.1.1 // indirect github.com/coredns/corefile-migration v1.0.20 // indirect + github.com/cyphar/filepath-securejoin v0.2.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect diff --git a/test/go.sum b/test/go.sum index a75f84234c..08463b3872 100644 --- a/test/go.sum +++ b/test/go.sum @@ -37,6 +37,8 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 h1:EKPd1INOIyr5hWOWhvpmQpY6tKjeG0hT1s3AMC/9fic= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1/go.mod h1:VzwV+t+dZ9j/H867F1M2ziD+yLHtB46oM35FxxMJ4d0= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.0.0 h1:dtDWrepsVPfW9H/4y7dDgFc2MBUSeJhlaDtK13CxFlU= @@ -104,6 +106,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsr github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI= +github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=