mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-05 15:37:19 +00:00
268 lines
5 KiB
Go
268 lines
5 KiB
Go
package fuzz
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
|
|
fuzz "github.com/AdaLogics/go-fuzz-headers"
|
|
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
|
admissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1"
|
|
)
|
|
|
|
func CreatePolicySpec(ff *fuzz.ConsumeFuzzer) (kyvernov1.Spec, error) {
|
|
spec := &kyvernov1.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 := kyvernov1.ApplyAll
|
|
spec.ApplyRules = &aa
|
|
} else {
|
|
ao := kyvernov1.ApplyOne
|
|
spec.ApplyRules = &ao
|
|
}
|
|
|
|
failPolicy, err := ff.GetBool()
|
|
if err != nil {
|
|
return *spec, err
|
|
}
|
|
if failPolicy {
|
|
fa := kyvernov1.Fail
|
|
spec.FailurePolicy = &fa
|
|
} else {
|
|
ig := kyvernov1.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([]kyvernov1.ValidationFailureActionOverride, 0)
|
|
err = ff.CreateSlice(&vfao)
|
|
if err != nil {
|
|
return *spec, err
|
|
}
|
|
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
|
|
|
|
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) []kyvernov1.Rule {
|
|
rules := make([]kyvernov1.Rule, 0)
|
|
noOfRules, err := ff.GetInt()
|
|
if err != nil {
|
|
return rules
|
|
}
|
|
var (
|
|
wg sync.WaitGroup
|
|
m sync.Mutex
|
|
)
|
|
for i := 0; i < noOfRules%100; i++ {
|
|
ruleBytes, err := ff.GetBytes()
|
|
if err != nil {
|
|
return rules
|
|
}
|
|
wg.Add(1)
|
|
ff1 := fuzz.NewConsumer(ruleBytes)
|
|
go func(ff2 *fuzz.ConsumeFuzzer) {
|
|
defer wg.Done()
|
|
rule, err := createRule(ff2)
|
|
if err != nil {
|
|
return
|
|
}
|
|
m.Lock()
|
|
rules = append(rules, *rule)
|
|
m.Unlock()
|
|
}(ff1)
|
|
}
|
|
wg.Wait()
|
|
return rules
|
|
}
|
|
|
|
// Creates a single rule
|
|
func createRule(f *fuzz.ConsumeFuzzer) (*kyvernov1.Rule, error) {
|
|
rule := &kyvernov1.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([]kyvernov1.ContextEntry, 0)
|
|
err = f.CreateSlice(&c)
|
|
if err != nil {
|
|
return rule, err
|
|
}
|
|
if len(c) != 0 {
|
|
rule.Context = c
|
|
}
|
|
}
|
|
|
|
mr := &kyvernov1.MatchResources{}
|
|
err = f.GenerateStruct(mr)
|
|
if err != nil {
|
|
return rule, err
|
|
}
|
|
rule.MatchResources = *mr
|
|
|
|
setExcludeResources, err := f.GetBool()
|
|
if err != nil {
|
|
return rule, err
|
|
}
|
|
if setExcludeResources {
|
|
er := &kyvernov1.MatchResources{}
|
|
err = f.GenerateStruct(mr)
|
|
if err != nil {
|
|
return rule, err
|
|
}
|
|
rule.ExcludeResources = *er
|
|
}
|
|
|
|
setRawAnyAllConditions, err := f.GetBool()
|
|
if err != nil {
|
|
return rule, err
|
|
}
|
|
if setRawAnyAllConditions {
|
|
raac := &kyvernov1.ConditionsWrapper{}
|
|
err = f.GenerateStruct(raac)
|
|
if err != nil {
|
|
return rule, err
|
|
}
|
|
rule.RawAnyAllConditions = raac
|
|
}
|
|
|
|
setCELPreconditions, err := f.GetBool()
|
|
if err != nil {
|
|
return rule, err
|
|
}
|
|
if setCELPreconditions {
|
|
celp := make([]admissionregistrationv1alpha1.MatchCondition, 0)
|
|
err = f.CreateSlice(&celp)
|
|
if err != nil {
|
|
return rule, err
|
|
}
|
|
if len(celp) != 0 {
|
|
rule.CELPreconditions = celp
|
|
}
|
|
}
|
|
|
|
setMutation, err := f.GetBool()
|
|
if err != nil {
|
|
return rule, err
|
|
}
|
|
if setMutation {
|
|
m := &kyvernov1.Mutation{}
|
|
err = f.GenerateStruct(m)
|
|
if err != nil {
|
|
return rule, err
|
|
}
|
|
rule.Mutation = *m
|
|
}
|
|
|
|
setValidation, err := f.GetBool()
|
|
if err != nil {
|
|
return rule, err
|
|
}
|
|
if setValidation {
|
|
v := &kyvernov1.Validation{}
|
|
err = f.GenerateStruct(v)
|
|
if err != nil {
|
|
return rule, err
|
|
}
|
|
rule.Validation = *v
|
|
}
|
|
|
|
setGeneration, err := f.GetBool()
|
|
if err != nil {
|
|
return rule, err
|
|
}
|
|
if setGeneration {
|
|
g := &kyvernov1.Generation{}
|
|
err = f.GenerateStruct(g)
|
|
if err != nil {
|
|
return rule, err
|
|
}
|
|
rule.Generation = *g
|
|
}
|
|
|
|
setVerifyImages, err := f.GetBool()
|
|
if err != nil {
|
|
return rule, err
|
|
}
|
|
if setVerifyImages {
|
|
iv := make([]kyvernov1.ImageVerification, 0)
|
|
err = f.CreateSlice(&iv)
|
|
if err != nil {
|
|
return rule, err
|
|
}
|
|
if len(iv) != 0 {
|
|
rule.VerifyImages = iv
|
|
}
|
|
}
|
|
|
|
return rule, nil
|
|
}
|