mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-05 07:26:55 +00:00
feat: add fuzzers from cncf-fuzzing (#8027)
* feat: add fuzzers from cncf-fuzzing Signed-off-by: AdamKorcz <adam@adalogics.com> * linter fixes Signed-off-by: ShutingZhao <shuting@nirmata.com> --------- Signed-off-by: AdamKorcz <adam@adalogics.com> Signed-off-by: ShutingZhao <shuting@nirmata.com> Co-authored-by: ShutingZhao <shuting@nirmata.com>
This commit is contained in:
parent
20bf9f235f
commit
98f57df5ae
9 changed files with 719 additions and 0 deletions
56
api/kyverno/v1/fuzz_test.go
Normal file
56
api/kyverno/v1/fuzz_test.go
Normal file
|
@ -0,0 +1,56 @@
|
|||
package v1
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
fuzz "github.com/AdaLogics/go-fuzz-headers"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
func FuzzV1PolicyValidate(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
ff := fuzz.NewConsumer(data)
|
||||
p := Policy{}
|
||||
ff.GenerateStruct(&p)
|
||||
_ = p.Validate(nil)
|
||||
})
|
||||
}
|
||||
|
||||
var (
|
||||
path = field.NewPath("dummy")
|
||||
)
|
||||
|
||||
func FuzzV1ImageVerification(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
ff := fuzz.NewConsumer(data)
|
||||
iv := ImageVerification{}
|
||||
ff.GenerateStruct(&iv)
|
||||
iv.Validate(false, path)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzV1MatchResources(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
ff := fuzz.NewConsumer(data)
|
||||
mr := &MatchResources{}
|
||||
ff.GenerateStruct(&mr)
|
||||
mr.Validate(path, false, nil)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzV1ClusterPolicy(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
ff := fuzz.NewConsumer(data)
|
||||
cp := &ClusterPolicy{}
|
||||
ff.GenerateStruct(&cp)
|
||||
cp.HasAutoGenAnnotation()
|
||||
cp.HasMutateOrValidateOrGenerate()
|
||||
cp.HasMutate()
|
||||
cp.HasValidate()
|
||||
cp.HasGenerate()
|
||||
cp.HasVerifyImages()
|
||||
cp.AdmissionProcessingEnabled()
|
||||
cp.BackgroundProcessingEnabled()
|
||||
cp.Validate(nil)
|
||||
})
|
||||
}
|
57
api/kyverno/v2beta1/fuzz_test.go
Normal file
57
api/kyverno/v2beta1/fuzz_test.go
Normal file
|
@ -0,0 +1,57 @@
|
|||
package v2beta1
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
fuzz "github.com/AdaLogics/go-fuzz-headers"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
func FuzzV2beta1PolicyValidate(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
ff := fuzz.NewConsumer(data)
|
||||
p := Policy{}
|
||||
ff.GenerateStruct(&p)
|
||||
_ = p.Validate(nil)
|
||||
})
|
||||
}
|
||||
|
||||
var (
|
||||
path = field.NewPath("dummy")
|
||||
)
|
||||
|
||||
func FuzzV2beta1ImageVerification(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
ff := fuzz.NewConsumer(data)
|
||||
iv := ImageVerification{}
|
||||
ff.GenerateStruct(&iv)
|
||||
iv.Validate(false, path)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzV2beta1MatchResources(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
ff := fuzz.NewConsumer(data)
|
||||
mr := &MatchResources{}
|
||||
ff.GenerateStruct(&mr)
|
||||
mr.ValidateResourceWithNoUserInfo(path, false, nil)
|
||||
mr.Validate(path, false, nil)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzV2beta1ClusterPolicy(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
ff := fuzz.NewConsumer(data)
|
||||
cp := &ClusterPolicy{}
|
||||
ff.GenerateStruct(&cp)
|
||||
cp.HasAutoGenAnnotation()
|
||||
cp.HasMutateOrValidateOrGenerate()
|
||||
cp.HasMutate()
|
||||
cp.HasValidate()
|
||||
cp.HasGenerate()
|
||||
cp.HasVerifyImages()
|
||||
cp.AdmissionProcessingEnabled()
|
||||
cp.BackgroundProcessingEnabled()
|
||||
cp.Validate(nil)
|
||||
})
|
||||
}
|
1
go.mod
1
go.mod
|
@ -3,6 +3,7 @@ module github.com/kyverno/kyverno
|
|||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1
|
||||
github.com/IGLOU-EU/go-wildcard v1.0.3
|
||||
github.com/Masterminds/sprig/v3 v3.2.3
|
||||
github.com/aquilax/truncate v1.0.0
|
||||
|
|
2
go.sum
2
go.sum
|
@ -59,6 +59,8 @@ dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
|||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek=
|
||||
filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
|
||||
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/AdamKorcz/go-fuzz-headers-1 v0.0.0-20230329111138-12e09aba5ebd h1:1tbEqR4NyQLgiod7vLXSswHteGetAVZrMGCqrJxLKRs=
|
||||
github.com/AliyunContainerService/ack-ram-tool/pkg/credentials/alibabacloudsdkgo/helper v0.2.0 h1:8+4G8JaejP8Xa6W46PzJEwisNgBXMvFcz78N6zG/ARw=
|
||||
github.com/AliyunContainerService/ack-ram-tool/pkg/credentials/alibabacloudsdkgo/helper v0.2.0/go.mod h1:GgeIE+1be8Ivm7Sh4RgwI42aTtC9qrcj+Y9Y6CjJhJs=
|
||||
|
|
11
pkg/engine/anchor/fuzz_test.go
Normal file
11
pkg/engine/anchor/fuzz_test.go
Normal file
|
@ -0,0 +1,11 @@
|
|||
package anchor
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func FuzzAnchorParseTest(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data string) {
|
||||
_ = Parse(data)
|
||||
})
|
||||
}
|
33
pkg/engine/api/fuzz_test.go
Normal file
33
pkg/engine/api/fuzz_test.go
Normal file
|
@ -0,0 +1,33 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
fuzz "github.com/AdaLogics/go-fuzz-headers"
|
||||
|
||||
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
||||
)
|
||||
|
||||
func FuzzEngineResponse(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
ff := fuzz.NewConsumer(data)
|
||||
|
||||
resource, err := ff.GetBytes()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(resource)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
namespaceLabels := make(map[string]string)
|
||||
ff.FuzzMap(&namespaceLabels)
|
||||
resp := NewEngineResponse(*resourceUnstructured, nil, namespaceLabels)
|
||||
_ = resp.GetPatches()
|
||||
_ = resp.GetFailedRules()
|
||||
_ = resp.GetFailedRulesWithErrors()
|
||||
_ = resp.GetValidationFailureAction()
|
||||
_ = resp.GetSuccessRules()
|
||||
})
|
||||
}
|
465
pkg/engine/fuzz_test.go
Normal file
465
pkg/engine/fuzz_test.go
Normal file
|
@ -0,0 +1,465 @@
|
|||
package engine
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
||||
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
|
||||
apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
|
||||
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
"github.com/kyverno/kyverno/pkg/autogen"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
"github.com/kyverno/kyverno/pkg/engine/adapters"
|
||||
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
|
||||
"github.com/kyverno/kyverno/pkg/engine/factories"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"github.com/kyverno/kyverno/pkg/engine/policycontext"
|
||||
"github.com/kyverno/kyverno/pkg/imageverifycache"
|
||||
"github.com/kyverno/kyverno/pkg/registryclient"
|
||||
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
||||
|
||||
fuzz "github.com/AdaLogics/go-fuzz-headers"
|
||||
)
|
||||
|
||||
/*
|
||||
VerifyAndPatchImage
|
||||
*/
|
||||
var (
|
||||
fuzzCfg = config.NewDefaultConfiguration(false)
|
||||
fuzzMetricsCfg = config.NewDefaultMetricsConfiguration()
|
||||
fuzzJp = jmespath.New(fuzzCfg)
|
||||
|
||||
validateContext = context.Background()
|
||||
regClient = registryclient.NewOrDie()
|
||||
validateEngine = NewEngine(
|
||||
fuzzCfg,
|
||||
config.NewDefaultMetricsConfiguration(),
|
||||
fuzzJp,
|
||||
nil,
|
||||
factories.DefaultRegistryClientFactory(adapters.RegistryClient(regClient), nil),
|
||||
imageverifycache.DisabledImageVerifyCache(),
|
||||
factories.DefaultContextLoaderFactory(nil),
|
||||
nil,
|
||||
"",
|
||||
)
|
||||
)
|
||||
|
||||
func buildFuzzContext(policy, resource, oldResource []byte) (*PolicyContext, error) {
|
||||
var cpol kyverno.ClusterPolicy
|
||||
err := json.Unmarshal([]byte(policy), &cpol)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(resource)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
policyContext, err := policycontext.NewPolicyContext(
|
||||
fuzzJp,
|
||||
*resourceUnstructured,
|
||||
kyverno.Create,
|
||||
nil,
|
||||
fuzzCfg,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
policyContext = policyContext.
|
||||
WithPolicy(&cpol).
|
||||
WithNewResource(*resourceUnstructured)
|
||||
|
||||
if !bytes.Equal(oldResource, []byte("")) {
|
||||
oldResourceUnstructured, err := kubeutils.BytesToUnstructured(oldResource)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = enginecontext.AddOldResource(policyContext.JSONContext(), oldResource)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
policyContext = policyContext.WithOldResource(*oldResourceUnstructured)
|
||||
}
|
||||
|
||||
return policyContext, nil
|
||||
}
|
||||
|
||||
func FuzzVerifyImageAndPatchTest(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, policy, resource, oldResource []byte) {
|
||||
pc, err := buildFuzzContext(policy, resource, oldResource)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
verifyImageAndPatchEngine := NewEngine(
|
||||
cfg,
|
||||
fuzzMetricsCfg,
|
||||
fuzzJp,
|
||||
nil,
|
||||
factories.DefaultRegistryClientFactory(adapters.RegistryClient(registryclient.NewOrDie()), nil),
|
||||
imageverifycache.DisabledImageVerifyCache(),
|
||||
factories.DefaultContextLoaderFactory(nil),
|
||||
nil,
|
||||
"",
|
||||
)
|
||||
|
||||
_, _ = verifyImageAndPatchEngine.VerifyAndPatchImages(
|
||||
context.Background(),
|
||||
pc,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/*
|
||||
Validate
|
||||
*/
|
||||
func createPolicySpec(ff *fuzz.ConsumeFuzzer) (kyverno.Spec, error) {
|
||||
spec := &kyverno.Spec{}
|
||||
rules := createRules(ff)
|
||||
if len(rules) == 0 {
|
||||
return *spec, fmt.Errorf("no rules")
|
||||
}
|
||||
spec.Rules = rules
|
||||
|
||||
applyAll, err := ff.GetBool()
|
||||
if err != nil {
|
||||
return *spec, err
|
||||
}
|
||||
if applyAll {
|
||||
aa := kyverno.ApplyAll
|
||||
spec.ApplyRules = &aa
|
||||
} else {
|
||||
ao := kyverno.ApplyOne
|
||||
spec.ApplyRules = &ao
|
||||
}
|
||||
|
||||
failPolicy, err := ff.GetBool()
|
||||
if err != nil {
|
||||
return *spec, err
|
||||
}
|
||||
if failPolicy {
|
||||
fa := kyverno.Fail
|
||||
spec.FailurePolicy = &fa
|
||||
} else {
|
||||
ig := kyverno.Ignore
|
||||
spec.FailurePolicy = &ig
|
||||
}
|
||||
|
||||
setValidationFailureAction, err := ff.GetBool()
|
||||
if err != nil {
|
||||
return *spec, err
|
||||
}
|
||||
if setValidationFailureAction {
|
||||
audit, err := ff.GetBool()
|
||||
if err != nil {
|
||||
return *spec, err
|
||||
}
|
||||
if audit {
|
||||
spec.ValidationFailureAction = "Audit"
|
||||
} else {
|
||||
spec.ValidationFailureAction = "Enforce"
|
||||
}
|
||||
}
|
||||
|
||||
setValidationFailureActionOverrides, err := ff.GetBool()
|
||||
if err != nil {
|
||||
return *spec, err
|
||||
}
|
||||
if setValidationFailureActionOverrides {
|
||||
vfao := make([]kyverno.ValidationFailureActionOverride, 0)
|
||||
ff.CreateSlice(&vfao)
|
||||
if len(vfao) != 0 {
|
||||
spec.ValidationFailureActionOverrides = vfao
|
||||
}
|
||||
}
|
||||
|
||||
admission, err := ff.GetBool()
|
||||
if err != nil {
|
||||
return *spec, err
|
||||
}
|
||||
spec.Admission = &admission
|
||||
|
||||
background, err := ff.GetBool()
|
||||
if err != nil {
|
||||
return *spec, err
|
||||
}
|
||||
spec.Background = &background
|
||||
|
||||
schemaValidation, err := ff.GetBool()
|
||||
if err != nil {
|
||||
return *spec, err
|
||||
}
|
||||
spec.SchemaValidation = &schemaValidation
|
||||
|
||||
mutateExistingOnPolicyUpdate, err := ff.GetBool()
|
||||
if err != nil {
|
||||
return *spec, err
|
||||
}
|
||||
spec.MutateExistingOnPolicyUpdate = mutateExistingOnPolicyUpdate
|
||||
|
||||
generateExistingOnPolicyUpdate, err := ff.GetBool()
|
||||
if err != nil {
|
||||
return *spec, err
|
||||
}
|
||||
spec.GenerateExistingOnPolicyUpdate = &generateExistingOnPolicyUpdate
|
||||
|
||||
generateExisting, err := ff.GetBool()
|
||||
if err != nil {
|
||||
return *spec, err
|
||||
}
|
||||
spec.GenerateExisting = generateExisting
|
||||
|
||||
return *spec, nil
|
||||
}
|
||||
|
||||
// Creates a slice of Rules
|
||||
func createRules(ff *fuzz.ConsumeFuzzer) []kyverno.Rule {
|
||||
rules := make([]kyverno.Rule, 0)
|
||||
noOfRules, err := ff.GetInt()
|
||||
if err != nil {
|
||||
return rules
|
||||
}
|
||||
for i := 0; i < noOfRules%100; i++ {
|
||||
rule, err := createRule(ff)
|
||||
if err != nil {
|
||||
return rules
|
||||
}
|
||||
|
||||
rules = append(rules, *rule)
|
||||
}
|
||||
return rules
|
||||
}
|
||||
|
||||
// Creates a single rule
|
||||
func createRule(f *fuzz.ConsumeFuzzer) (*kyverno.Rule, error) {
|
||||
rule := &kyverno.Rule{}
|
||||
name, err := f.GetString()
|
||||
if err != nil {
|
||||
return rule, err
|
||||
}
|
||||
rule.Name = name
|
||||
|
||||
setContext, err := f.GetBool()
|
||||
if err != nil {
|
||||
return rule, err
|
||||
}
|
||||
if setContext {
|
||||
c := make([]kyverno.ContextEntry, 0)
|
||||
f.CreateSlice(&c)
|
||||
if len(c) != 0 {
|
||||
rule.Context = c
|
||||
}
|
||||
}
|
||||
|
||||
mr := &kyverno.MatchResources{}
|
||||
f.GenerateStruct(mr)
|
||||
rule.MatchResources = *mr
|
||||
|
||||
setExcludeResources, err := f.GetBool()
|
||||
if err != nil {
|
||||
return rule, err
|
||||
}
|
||||
if setExcludeResources {
|
||||
er := &kyverno.MatchResources{}
|
||||
f.GenerateStruct(mr)
|
||||
rule.ExcludeResources = *er
|
||||
}
|
||||
|
||||
setRawAnyAllConditions, err := f.GetBool()
|
||||
if err != nil {
|
||||
return rule, err
|
||||
}
|
||||
if setRawAnyAllConditions {
|
||||
raac := &apiextv1.JSON{}
|
||||
f.GenerateStruct(raac)
|
||||
rule.RawAnyAllConditions = raac
|
||||
}
|
||||
|
||||
setCELPreconditions, err := f.GetBool()
|
||||
if err != nil {
|
||||
return rule, err
|
||||
}
|
||||
if setCELPreconditions {
|
||||
celp := make([]admissionregistrationv1.MatchCondition, 0)
|
||||
f.CreateSlice(&celp)
|
||||
if len(celp) != 0 {
|
||||
rule.CELPreconditions = celp
|
||||
}
|
||||
}
|
||||
|
||||
setMutation, err := f.GetBool()
|
||||
if err != nil {
|
||||
return rule, err
|
||||
}
|
||||
if setMutation {
|
||||
m := &kyverno.Mutation{}
|
||||
f.GenerateStruct(m)
|
||||
rule.Mutation = *m
|
||||
}
|
||||
|
||||
setValidation, err := f.GetBool()
|
||||
if err != nil {
|
||||
return rule, err
|
||||
}
|
||||
if setValidation {
|
||||
v := &kyverno.Validation{}
|
||||
f.GenerateStruct(v)
|
||||
rule.Validation = *v
|
||||
}
|
||||
|
||||
setGeneration, err := f.GetBool()
|
||||
if err != nil {
|
||||
return rule, err
|
||||
}
|
||||
if setGeneration {
|
||||
g := &kyverno.Generation{}
|
||||
f.GenerateStruct(g)
|
||||
rule.Generation = *g
|
||||
}
|
||||
|
||||
setVerifyImages, err := f.GetBool()
|
||||
if err != nil {
|
||||
return rule, err
|
||||
}
|
||||
if setVerifyImages {
|
||||
iv := make([]kyverno.ImageVerification, 0)
|
||||
f.CreateSlice(&iv)
|
||||
if len(iv) != 0 {
|
||||
rule.VerifyImages = iv
|
||||
}
|
||||
}
|
||||
|
||||
return rule, nil
|
||||
}
|
||||
|
||||
func FuzzEngineValidateTest(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
ff := fuzz.NewConsumer(data)
|
||||
//ff.GenerateStruct(policy)
|
||||
cpSpec, err := createPolicySpec(ff)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
policy := &kyverno.ClusterPolicy{}
|
||||
policy.Spec = cpSpec
|
||||
|
||||
if len(autogen.ComputeRules(policy)) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
resourceUnstructured, err := createUnstructuredObject(ff)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
pc, err := NewPolicyContext(fuzzJp, *resourceUnstructured, kyverno.Create, nil, fuzzCfg)
|
||||
if err != nil {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
validateEngine.Validate(
|
||||
validateContext,
|
||||
pc.WithPolicy(policy),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
// Creates an unstructured k8s object
|
||||
func createUnstructuredObject(f *fuzz.ConsumeFuzzer) (*unstructured.Unstructured, error) {
|
||||
var sb strings.Builder
|
||||
|
||||
sb.WriteString("{ \"apiVersion\": \"apps/v1\", \"kind\": \"Deployment\", \"metadata\": { \"creationTimestamp\": \"2020-09-21T12:56:35Z\", \"name\": \"fuzz\", \"labels\": { \"test\": \"qos\" } }, \"spec\": { ")
|
||||
|
||||
for i := 0; i < 1000; i++ {
|
||||
typeToAdd, err := f.GetInt()
|
||||
if err != nil {
|
||||
return kubeutils.BytesToUnstructured([]byte(sb.String()))
|
||||
}
|
||||
switch typeToAdd % 11 {
|
||||
case 0:
|
||||
sb.WriteString("\"")
|
||||
case 1:
|
||||
s, err := f.GetString()
|
||||
if err != nil {
|
||||
return kubeutils.BytesToUnstructured([]byte(sb.String()))
|
||||
}
|
||||
sb.WriteString(s)
|
||||
case 2:
|
||||
sb.WriteString("{")
|
||||
case 3:
|
||||
sb.WriteString("}")
|
||||
case 4:
|
||||
sb.WriteString("[")
|
||||
case 5:
|
||||
sb.WriteString("]")
|
||||
case 6:
|
||||
sb.WriteString(":")
|
||||
case 7:
|
||||
sb.WriteString(",")
|
||||
case 8:
|
||||
sb.WriteString(" ")
|
||||
case 9:
|
||||
sb.WriteString("\t")
|
||||
case 10:
|
||||
sb.WriteString("\n")
|
||||
}
|
||||
}
|
||||
return kubeutils.BytesToUnstructured([]byte(sb.String()))
|
||||
}
|
||||
|
||||
/*
|
||||
Mutate
|
||||
*/
|
||||
func FuzzMutateTest(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, resourceRaw, policyRaw []byte) {
|
||||
var policy kyverno.ClusterPolicy
|
||||
err := json.Unmarshal(policyRaw, &policy)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var resource unstructured.Unstructured
|
||||
err = resource.UnmarshalJSON(resourceRaw)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// create policy context
|
||||
pc, err := NewPolicyContext(
|
||||
fuzzJp,
|
||||
resource,
|
||||
kyverno.Create,
|
||||
nil,
|
||||
fuzzCfg,
|
||||
)
|
||||
if err != nil {
|
||||
t.Skip()
|
||||
}
|
||||
e := NewEngine(
|
||||
fuzzCfg,
|
||||
config.NewDefaultMetricsConfiguration(),
|
||||
fuzzJp,
|
||||
adapters.Client(nil),
|
||||
factories.DefaultRegistryClientFactory(adapters.RegistryClient(nil), nil),
|
||||
imageverifycache.DisabledImageVerifyCache(),
|
||||
factories.DefaultContextLoaderFactory(nil),
|
||||
nil,
|
||||
"",
|
||||
)
|
||||
e.Mutate(
|
||||
context.Background(),
|
||||
pc.WithPolicy(&policy),
|
||||
)
|
||||
panic("Here")
|
||||
})
|
||||
}
|
62
pkg/engine/variables/fuzz_test.go
Normal file
62
pkg/engine/variables/fuzz_test.go
Normal file
|
@ -0,0 +1,62 @@
|
|||
package variables
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
fuzz "github.com/AdaLogics/go-fuzz-headers"
|
||||
"github.com/go-logr/logr"
|
||||
|
||||
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
"github.com/kyverno/kyverno/pkg/engine/context"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
)
|
||||
|
||||
var (
|
||||
ConditionOperators = []kyverno.ConditionOperator{
|
||||
kyverno.ConditionOperator("Equal"),
|
||||
kyverno.ConditionOperator("Equals"),
|
||||
kyverno.ConditionOperator("NotEqual"),
|
||||
kyverno.ConditionOperator("NotEquals"),
|
||||
kyverno.ConditionOperator("In"),
|
||||
kyverno.ConditionOperator("AnyIn"),
|
||||
kyverno.ConditionOperator("AllIn"),
|
||||
kyverno.ConditionOperator("NotIn"),
|
||||
kyverno.ConditionOperator("AnyNotIn"),
|
||||
kyverno.ConditionOperator("AllNotIn"),
|
||||
kyverno.ConditionOperator("GreaterThanOrEquals"),
|
||||
kyverno.ConditionOperator("GreaterThan"),
|
||||
kyverno.ConditionOperator("LessThanOrEquals"),
|
||||
kyverno.ConditionOperator("LessThan"),
|
||||
kyverno.ConditionOperator("DurationGreaterThanOrEquals"),
|
||||
kyverno.ConditionOperator("DurationGreaterThan"),
|
||||
kyverno.ConditionOperator("DurationLessThanOrEquals"),
|
||||
kyverno.ConditionOperator("DurationLessThan"),
|
||||
}
|
||||
)
|
||||
|
||||
func FuzzEvaluate(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
ff := fuzz.NewConsumer(data)
|
||||
jsonData1, err := ff.GetBytes()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
operator, err := ff.GetInt()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
jsonData2, err := ff.GetBytes()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
o := ConditionOperators[operator%len(ConditionOperators)]
|
||||
cond := kyverno.Condition{
|
||||
RawKey: kyverno.ToJSON(jsonData1),
|
||||
Operator: o,
|
||||
RawValue: kyverno.ToJSON(jsonData2),
|
||||
}
|
||||
ctx := context.NewContext(jmespath.New(config.NewDefaultConfiguration(false)))
|
||||
_, _, _ = Evaluate(logr.Discard(), ctx, cond)
|
||||
})
|
||||
}
|
32
pkg/validation/policy/fuzz_test.go
Normal file
32
pkg/validation/policy/fuzz_test.go
Normal file
|
@ -0,0 +1,32 @@
|
|||
package policy
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
|
||||
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
"github.com/kyverno/kyverno/pkg/openapi"
|
||||
|
||||
fuzz "github.com/AdaLogics/go-fuzz-headers"
|
||||
)
|
||||
|
||||
var fuzzOpenApiManager openapi.Manager
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
fuzzOpenApiManager, err = openapi.NewManager(logr.Discard())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func FuzzValidatePolicy(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
ff := fuzz.NewConsumer(data)
|
||||
p := &kyverno.ClusterPolicy{}
|
||||
ff.GenerateStruct(p)
|
||||
|
||||
Validate(p, nil, nil, true, fuzzOpenApiManager, "admin")
|
||||
})
|
||||
}
|
Loading…
Add table
Reference in a new issue