Documentation ¶
Index ¶
- Constants
- Variables
- func AddValueToValueToFieldsMap(valueToFieldsMap map[ssa.Value]TypeFieldNodeSet, value ssa.Value, ...) bool
- func BackwardPropagationHelper(context *Context, value ssa.Value) (sources []*pointer.Label)
- func BackwardPropogation(addr ssa.Value, taintedSet map[ssa.Value]bool) (taintedParam int, changed bool)
- func BackwardPropogationHelper(value ssa.Value, path []int, taintedSet map[ssa.Value]bool, ...) (addrSources []ssa.Value)
- func BlockDominees(context *Context, bb *ssa.BasicBlock, branch bool) (dominees []*ssa.BasicBlock)
- func BranchDominees(context *Context, bb *ssa.BasicBlock) (trueDominees, falseDominees []*ssa.BasicBlock)
- func ContextAwareFunctionAnalysis(context *Context, value ssa.Value, callInst ssa.CallInstruction, ...) (end bool, taintedArgs []ssa.Value, taintedRets []ssa.Value)
- func Dominators(context *Context, frontierSet map[ssa.Value]bool)
- func DumpKnownFunctions()
- func ExternalLibrary(context *Context, fn *ssa.Function) bool
- func FindAllUses(context *Context)
- func FindDefaultAssignment(context *Context, ifBlock *ssa.BasicBlock, branch bool, ...)
- func FindDirectBranches(context *Context, source ssa.Value)
- func FindDirectBranchesHelper(context *Context, conditionValue ssa.Value, binopValue *ssa.BinOp, ...)
- func FindFunctionDominees(context *Context, bbs []*ssa.BasicBlock) (dominees []*ssa.Function)
- func FindUsesInBlocks(context *Context, blocks []*ssa.BasicBlock, ...) map[ssa.Value]bool
- func FindUsesInConditions(context *Context, frontierSet map[ssa.Value]bool)
- func GetCopyOverFields(context *Context) (fields util.FieldSet)
- func GetDefaultValue(context *Context, frontierValues map[ssa.Value]bool, ...)
- func GetFieldToK8sMapping(context *Context, prog *ssa.Program, seedType *string, seedPkgPath *string)
- func GetTypeTree(context *Context, seedType types.Type)
- func GetTypeTreeHelper(context *Context, seedType types.Type, node *TypeFieldNode)
- func GetValueToFieldMappingPass(context *Context, prog *ssa.Program, seedType *string, seedPkgPath *string) (map[ssa.Value]*FieldSet, map[ssa.Value]bool)
- func GlobalAssignments(global *ssa.Global) (ret []ssa.Instruction)
- func HandleStructField(context *Context, originalTaintedStructValue *TaintedStructValue) (ret map[ssa.Value]bool)
- func IsInterfaceFunctionSink(function *types.Func) bool
- func IsK8sInterfaceFunction(function *types.Func) bool
- func IsK8sStaticFunction(function *ssa.Function) bool
- func IsKubernetesType(t types.Type) bool
- func IsStaticFunctionSink(function *ssa.Function) bool
- func Negation(op token.Token) token.Token
- func PropagateToCallee(context *Context, callee *ssa.Function, callSiteTaintedArgIndexSet []int, ...)
- func PropogateToCallee(context *Context, callee *ssa.Function, value ssa.Value, ...)
- func PropogateToConditions(context *Context, source ssa.Value) (branches map[*ssa.If]PropogatedValue)
- func ReachableBlocks(context *Context, bb *ssa.BasicBlock, stop *ssa.BasicBlock) (reachSet map[*ssa.BasicBlock]bool)
- func SimplyBackwardPropogation(context *Context, value ssa.Value) ssa.Value
- func StructBackwardPropagation(value ssa.Value, path []int) (ssa.Value, []int)
- func StructFieldPropagateToCallee(context *Context, worklist *[]*TaintedStructValue, callee *ssa.Function, ...)
- func TaintAnalysisPass(context *Context, prog *ssa.Program, frontierValues map[ssa.Value]bool, ...) *FieldSet
- func TaintFunction(context *Context, functionBody *ssa.Function, entryPoints []ssa.Value, ...) (end bool, taintedParams []int, taintedRets []int)
- func TaintK8sFromValue(context *Context, value ssa.Value, originalValue ssa.Value, ...) bool
- func TryGetValueForAddr(addr ssa.Value) *ssa.Const
- func TryGetValueForAlloc(alloc *ssa.Alloc) *ssa.Const
- func TryGetValueForStructAlloc(alloc *ssa.Alloc) *ssa.Const
- func TryResolveValue(value ssa.Value) *ssa.Const
- func UpdateValueInValueFieldSetMap(context *Context, value ssa.Value, parentFieldSet *FieldSet, ...) (changed bool)
- type BranchCondition
- type CallStack
- type ConcreteCondition
- type ConcreteConditionSet
- func (ccs *ConcreteConditionSet) Add(cg *ConditionGroup)
- func (ccs *ConcreteConditionSet) Contain(cc string) bool
- func (ccs *ConcreteConditionSet) Extend(cgList ...*ConditionGroup)
- func (ccs *ConcreteConditionSet) Intersect(ccs_ *ConcreteConditionSet) *ConcreteConditionSet
- func (ccs *ConcreteConditionSet) ToPlainConditionSet(path []string) *PlainConcreteConditionSet
- type ConditionGroup
- type ConditionGroupType
- type Context
- type DataPath
- type FieldInKubernetes
- type FieldInKubernetesSlice
- type FieldNode
- type FieldNodeSet
- type FunctionCall
- type FunctionTaintResult
- type PlainConcreteConditionSet
- type PlainCondition
- type PlainConditionGroup
- type PostDominator
- type PropogatedValue
- type ReferredInstruction
- type StringSet
- type TaintedStructValue
- type TypeFieldNode
- type TypeFieldNodeSet
- type UsesInBranch
- type ValueToFieldNodeSetMap
Constants ¶
const INDEX = "ITEM"
const MAP_KEY = "KEY"
Variables ¶
var ( PackageSinks = map[string]bool{ "log": true, "reflect": true, "regexp": true, "github.com/pkg/errors": true, "github.com/go-logr/logr": true, "go.uber.org/zap": true, "github.com/go-openapi/runtime": true, "k8s.io/klog/v2": true, "github.com/Azure/azure-storage-blob-go/azblob": true, "github.com/hashicorp/go-version": true, "database/sql": true, "k8s.io/client-go/testing": true, "k8s.io/apimachinery/pkg/util/errors": true, "k8s.io/client-go/listers/core/v1": true, } StructSinks = map[string]bool{ "(*k8s.io/apimachinery/pkg/apis/meta/v1/unstructured.Unstructured)": true, } InterfaceFunctionSinks = map[string]bool{ "(k8s.io/client-go/kubernetes/typed/apps/v1.StatefulSetsGetter).StatefulSets": true, "(k8s.io/client-go/kubernetes/typed/apps/v1.StatefulSetInterface).Get": true, "(k8s.io/client-go/kubernetes/typed/core/v1.PersistentVolumeClaimInterface).Get": true, "(k8s.io/client-go/kubernetes/typed/core/v1.PersistentVolumeClaimsGetter).PersistentVolumeClaims": true, "(github.com/go-logr/logr.Logger).Error": true, "(github.com/go-logr/logr.Logger).Info": true, "(k8s.io/client-go/tools/record.EventRecorder).Event": true, "(k8s.io/apimachinery/pkg/apis/meta/v1.Object).GetLabels": true, "(*k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta).GetNamespace": true, "(k8s.io/apimachinery/pkg/apis/meta/v1.Object).GetName": true, "(k8s.io/client-go/tools/record.EventRecorder).Eventf": true, "(sigs.k8s.io/controller-runtime/pkg/client.Reader).List": true, "(sigs.k8s.io/controller-runtime/pkg/client.StatusClient).Status": true, "(k8s.io/apimachinery/pkg/apis/meta/v1.Object).SetOwnerReferences": true, "(k8s.io/apimachinery/pkg/apis/meta/v1.Object).GetOwnerReferences": true, "k8s.io/apimachinery/pkg/apis/meta/v1.IsControlledBy": true, "(sigs.k8s.io/controller-runtime/pkg/controller.Controller).Watch": true, "(k8s.io/apimachinery/pkg/runtime.Object).GetObjectKind": true, "(k8s.io/client-go/util/workqueue.Interface).Add": true, "(k8s.io/client-go/listers/core/v1.PodLister).Pods": true, "(k8s.io/client-go/listers/core/v1.PersistentVolumeClaimLister).PersistentVolumeClaims": true, "(k8s.io/client-go/kubernetes/typed/core/v1.PodsGetter).Pods": true, "(k8s.io/client-go/kubernetes/typed/core/v1.SecretInterface).Get": true, "(k8s.io/apimachinery/pkg/runtime/schema.ObjectKind).GroupVersionKind": true, } StaticFunctionSinks = map[string]bool{ "context.WithTimeout": true, "fmt.Errorf": true, "fmt.Printf": true, "strings.Contains": true, "strings.Index": true, "(*k8s.io/client-go/rest.Request).Watch": true, "(*k8s.io/client-go/rest.Request).Stream": true, "(*encoding/json.Decoder).Decode": true, "k8s.io/client-go/kubernetes.NewForConfig": true, "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil.SetControllerReference": true, "(*sigs.k8s.io/controller-runtime/pkg/builder.WebhookBuilder).For": true, "(*sigs.k8s.io/controller-runtime/pkg/builder.WebhookBuilder).registerWebhooks": true, "(*sigs.k8s.io/controller-runtime/pkg/builder.Builder).For": true, "k8s.io/apimachinery/pkg/api/errors.NewBadRequest": true, "(*sigs.k8s.io/controller-runtime/pkg/scheme.Builder).Register": true, "sigs.k8s.io/controller-runtime/pkg/client/fake.NewFakeClient": true, "sigs.k8s.io/controller-runtime/pkg/client/apiutil.GVKForObject": true, "(*k8s.io/apimachinery/pkg/runtime.Scheme).AddKnownTypes": true, "k8s.io/kubernetes/pkg/util/hash.DeepHashObject": true, "unicode/utf8.Valid": true, "net.LookupIP": true, "(*net/http.Client).do": true, "sigs.k8s.io/controller-runtime/pkg/client.IgnoreNotFound": true, "(*github.com/hashicorp/go-version.Version).Compare": true, "(*k8s.io/client-go/rest.Request).Do": true, "k8s.io/client-go/transport/spdy.RoundTripperFor": true, "k8s.io/client-go/kubernetes.NewForConfigOrDie": true, "(*database/sql.DB).Exec": true, "(*k8s.io/apimachinery/pkg/apis/meta/v1/unstructured.Unstructured).SetName": true, "(*k8s.io/apimachinery/pkg/apis/meta/v1/unstructured.Unstructured).SetNamespace": true, "k8s.io/apimachinery/pkg/util/validation.IsConfigMapKey": true, "go.etcd.io/etcd/clientv3.New": true, "k8s.io/apimachinery/pkg/util/validation/field.Invalid": true, } KnownFunctionWithoutReceiver = map[string]FunctionTaintResult{ "DeepCopy": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "DeepCopyInto": { End: false, TaintedArgs: []int{1}, TaintedRets: []int{}, }, "DeepCopyObject": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, } KnownStaticFunction = map[FunctionCall]FunctionTaintResult{ { FunctionName: "(*sync.Map).LoadOrStore", TaintSource: fmt.Sprint([]int{1}), }: { End: false, TaintedArgs: []int{0}, TaintedRets: []int{}, }, { FunctionName: "strconv.ParseInt", TaintSource: fmt.Sprint([]int{0}), }: { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, { FunctionName: "strings.Replace", TaintSource: fmt.Sprint([]int{0}), }: { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, { FunctionName: "strings.ReplaceAll", TaintSource: fmt.Sprint([]int{0}), }: { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, { FunctionName: "(k8s.io/client-go/rest.Result).Into", TaintSource: fmt.Sprint([]int{1}), }: { End: false, TaintedArgs: []int{}, TaintedRets: []int{}, }, { FunctionName: "(*k8s.io/client-go/rest.Request).Body", TaintSource: fmt.Sprint([]int{0}), }: { End: false, TaintedArgs: []int{}, TaintedRets: []int{}, }, { FunctionName: "(*k8s.io/client-go/rest.Request).Body", TaintSource: fmt.Sprint([]int{1}), }: { End: true, TaintedArgs: []int{}, TaintedRets: []int{}, }, { FunctionName: "(*k8s.io/apimachinery/pkg/runtime.Scheme).Convert", TaintSource: fmt.Sprint([]int{1}), }: { End: false, TaintedArgs: []int{2}, TaintedRets: []int{}, }, { FunctionName: "(*k8s.io/apimachinery/pkg/runtime.Scheme).Convert", TaintSource: fmt.Sprint([]int{2}), }: { End: false, TaintedArgs: []int{}, TaintedRets: []int{}, }, { FunctionName: "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil.AddFinalizer", TaintSource: fmt.Sprint([]int{1}), }: { End: false, TaintedArgs: []int{0}, TaintedRets: []int{}, }, { FunctionName: "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil.AddFinalizer", TaintSource: fmt.Sprint([]int{0}), }: { End: false, TaintedArgs: []int{}, TaintedRets: []int{}, }, { FunctionName: "(*gopkg.in/ini.v1.File).Append", TaintSource: fmt.Sprint([]int{1}), }: { End: false, TaintedArgs: []int{0}, TaintedRets: []int{}, }, { FunctionName: "(*gopkg.in/ini.v1.File).Append", TaintSource: fmt.Sprint([]int{0}), }: { End: false, TaintedArgs: []int{}, TaintedRets: []int{}, }, { FunctionName: "(*gopkg.in/ini.v1.Section).NewKey", TaintSource: fmt.Sprint([]int{2}), }: { End: false, TaintedArgs: []int{0}, TaintedRets: []int{0}, }, { FunctionName: "(*gopkg.in/ini.v1.Section).NewKey", TaintSource: fmt.Sprint([]int{1}), }: { End: false, TaintedArgs: []int{0}, TaintedRets: []int{0}, }, { FunctionName: "(*gopkg.in/ini.v1.Section).NewKey", TaintSource: fmt.Sprint([]int{0}), }: { End: false, TaintedArgs: []int{}, TaintedRets: []int{}, }, { FunctionName: "(*gopkg.in/ini.v1.File).WriteTo", TaintSource: fmt.Sprint([]int{0}), }: { End: false, TaintedArgs: []int{1}, TaintedRets: []int{}, }, { FunctionName: "(*gopkg.in/ini.v1.File).WriteTo", TaintSource: fmt.Sprint([]int{1}), }: { End: false, TaintedArgs: []int{}, TaintedRets: []int{}, }, { FunctionName: "gopkg.in/yaml.v2.Unmarshal", TaintSource: fmt.Sprint([]int{0}), }: { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, { FunctionName: "(*text/template.Template).Execute", TaintSource: fmt.Sprint([]int{0}), }: { End: false, TaintedArgs: []int{1}, TaintedRets: []int{}, }, { FunctionName: "(*text/template.Template).Execute", TaintSource: fmt.Sprint([]int{1}), }: { End: false, TaintedArgs: []int{}, TaintedRets: []int{}, }, { FunctionName: "(*text/template.Template).Execute", TaintSource: fmt.Sprint([]int{2}), }: { End: false, TaintedArgs: []int{1}, TaintedRets: []int{}, }, { FunctionName: "sort.SliceStable", TaintSource: fmt.Sprint([]int{0}), }: { End: false, TaintedArgs: []int{}, TaintedRets: []int{}, }, } KnownStaticFunctionWithoutParam = map[string]FunctionTaintResult{ "fmt.Sprintf": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "fmt.Sprint": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "fmt.Fprintf": { End: false, TaintedArgs: []int{0}, TaintedRets: []int{}, }, "strings.Split": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "strings.EqualFold": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "strings.Join": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "strings.TrimSuffix": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "strings.HasPrefix": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "strings.TrimPrefix": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "strings.ToLower": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "strconv.Itoa": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "strconv.FormatBool": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "strconv.ParseFloat": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "sort.Strings": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "net/url.escape": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "net/url.Parse": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "net.ParseIP": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "net/http.NewRequest": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "(net/url.Values).Encode": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "encoding/json.Marshal": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "encoding/json.Unmarshal": { End: false, TaintedArgs: []int{1}, TaintedRets: []int{}, }, "encoding/pem.Decode": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0, 1}, }, "errors.Is": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "path/filepath.Join": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "path.Join": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "k8s.io/apimachinery/pkg/api/meta.Accessor": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "k8s.io/apimachinery/pkg/labels.SelectorFromSet": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "k8s.io/apimachinery/pkg/util/intstr.FromInt": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "k8s.io/apimachinery/pkg/api/resource.ParseQuantity": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "(*k8s.io/apimachinery/pkg/api/resource.Quantity).String": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "k8s.io/kubernetes/pkg/util/slice.ContainsString": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "k8s.io/apimachinery/pkg/util/validation.IsDNS1035Label": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "(*k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta).SetAnnotations": { End: false, TaintedArgs: []int{0}, TaintedRets: []int{}, }, "(*k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta).GetAnnotations": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil.ContainsFinalizer": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "sigs.k8s.io/controller-runtime/pkg/client.MergeFrom": { End: false, TaintedArgs: []int{}, TaintedRets: []int{}, }, "(*k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta).GetUID": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "(*k8s.io/apimachinery/pkg/apis/meta/v1.Time).IsZero": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "k8s.io/apimachinery/pkg/api/errors.IsNotFound": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "k8s.io/utils/pointer.Int32Deref": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "k8s.io/apimachinery/pkg/labels.Parse": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "(*k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta).GetName": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "(*k8s.io/apimachinery/pkg/api/resource.Quantity).Cmp": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "(k8s.io/apimachinery/pkg/api/resource.Quantity).Equal": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "(*k8s.io/api/core/v1.ResourceList).Memory": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "(*k8s.io/apimachinery/pkg/api/resource.Quantity).Value": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "(*k8s.io/apimachinery/pkg/api/resource.Quantity).IsZero": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "k8s.io/apimachinery/pkg/util/strategicpatch.StrategicMergePatch": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "(k8s.io/apimachinery/pkg/types.NamespacedName).String": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "(*k8s.io/client-go/rest.Request).VersionedParams": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "reflect.DeepEqual": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "(*k8s.io/client-go/rest.Request).URL": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "(*gopkg.in/ini.v1.File).Section": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "(*regexp.Regexp).MatchString": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "(*regexp.Regexp).FindAllString": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "regexp.Compile": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "github.com/hashicorp/go-version.NewVersion": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "github.com/hashicorp/go-version.Must": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, } KnownInterfaceFunction = map[FunctionCall]FunctionTaintResult{ { FunctionName: "(k8s.io/client-go/kubernetes/typed/core/v1.PersistentVolumeClaimInterface).Patch", TaintSource: fmt.Sprint([]int{3}), }: { End: true, TaintedArgs: []int{}, TaintedRets: []int{}, }, { FunctionName: "(k8s.io/client-go/kubernetes/typed/batch/v1.JobInterface).Create", TaintSource: fmt.Sprint([]int{1}), }: { End: true, TaintedArgs: []int{}, TaintedRets: []int{}, }, { FunctionName: "(k8s.io/client-go/kubernetes/typed/policy/v1.PodDisruptionBudgetInterface).Create", TaintSource: fmt.Sprint([]int{1}), }: { End: true, TaintedArgs: []int{}, TaintedRets: []int{}, }, { FunctionName: "(k8s.io/apimachinery/pkg/apis/meta/v1.Object).SetLabels", TaintSource: fmt.Sprint([]int{0}), }: { End: false, TaintedArgs: []int{-1}, TaintedRets: []int{}, }, { FunctionName: "(sigs.k8s.io/controller-runtime/pkg/client.Reader).List", TaintSource: fmt.Sprint([]int{2}), }: { End: false, TaintedArgs: []int{1}, TaintedRets: []int{}, }, { FunctionName: "(sigs.k8s.io/controller-runtime/pkg/client.Reader).List", TaintSource: fmt.Sprint([]int{1}), }: { End: false, TaintedArgs: []int{}, TaintedRets: []int{}, }, { FunctionName: "(sigs.k8s.io/controller-runtime/pkg/client.StatusWriter).Patch", TaintSource: fmt.Sprint([]int{0}), }: { End: false, TaintedArgs: []int{}, TaintedRets: []int{}, }, { FunctionName: "(sigs.k8s.io/controller-runtime/pkg/client.StatusWriter).Patch", TaintSource: fmt.Sprint([]int{1}), }: { End: true, TaintedArgs: []int{}, TaintedRets: []int{}, }, { FunctionName: "(sigs.k8s.io/controller-runtime/pkg/client.Writer).Patch", TaintSource: fmt.Sprint([]int{-1}), }: { End: false, TaintedArgs: []int{}, TaintedRets: []int{}, }, { FunctionName: "(sigs.k8s.io/controller-runtime/pkg/client.Writer).Patch", TaintSource: fmt.Sprint([]int{0}), }: { End: false, TaintedArgs: []int{}, TaintedRets: []int{}, }, { FunctionName: "(sigs.k8s.io/controller-runtime/pkg/client.Writer).Patch", TaintSource: fmt.Sprint([]int{1}), }: { End: true, TaintedArgs: []int{}, TaintedRets: []int{}, }, { FunctionName: "(sigs.k8s.io/controller-runtime/pkg/client.Writer).Patch", TaintSource: fmt.Sprint([]int{2}), }: { End: false, TaintedArgs: []int{}, TaintedRets: []int{}, }, { FunctionName: "(github.com/go-openapi/runtime.ClientTransport).Submith", TaintSource: fmt.Sprint([]int{-1}), }: { End: false, TaintedArgs: []int{}, TaintedRets: []int{}, }, } KnownInterfaceFunctionWithoutParam = map[string]FunctionTaintResult{ "(sigs.k8s.io/controller-runtime/pkg/client.Reader).Get": { End: false, TaintedArgs: []int{}, TaintedRets: []int{}, }, "(*k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta).GetName": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "(error).Error": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "(k8s.io/apimachinery/pkg/apis/meta/v1.Object).GetAnnotations": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "(k8s.io/apimachinery/pkg/labels.Selector).Add": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, "(k8s.io/apimachinery/pkg/runtime.Object).DeepCopyObject": { End: false, TaintedArgs: []int{}, TaintedRets: []int{0}, }, } K8sInterfaceFunctions = map[string]bool{ "(sigs.k8s.io/controller-runtime/pkg/client.Writer).Create": true, "(sigs.k8s.io/controller-runtime/pkg/client.Writer).Delete": true, "(sigs.k8s.io/controller-runtime/pkg/client.Writer).Update": true, "(k8s.io/apimachinery/pkg/apis/meta/v1.Object).SetAnnotations": true, "(sigs.k8s.io/controller-runtime/pkg/client.StatusWriter).Update": true, "(k8s.io/client-go/kubernetes/typed/core/v1.ConfigMapInterface).Create": true, "(k8s.io/client-go/kubernetes/typed/apps/v1.StatefulSetInterface).Create": true, "(k8s.io/client-go/kubernetes/typed/apps/v1.StatefulSetInterface).UpdateScale": true, "(k8s.io/client-go/kubernetes/typed/core/v1.ServiceInterface).Create": true, "(k8s.io/client-go/kubernetes/typed/apps/v1.DeploymentInterface).Create": true, "(k8s.io/client-go/kubernetes/typed/core/v1.PersistentVolumeClaimInterface).Update": true, } K8sStaticFunctions = map[string]bool{ "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil.RemoveFinalizer": true, "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil.CreateOrUpdate": true, "k8s.io/client-go/tools/remotecommand.NewSPDYExecutor": true, } )
Functions ¶
func AddValueToValueToFieldsMap ¶
func AddValueToValueToFieldsMap(valueToFieldsMap map[ssa.Value]TypeFieldNodeSet, value ssa.Value, fields TypeFieldNodeSet) bool
func BackwardPropogation ¶
func BackwardPropogation(addr ssa.Value, taintedSet map[ssa.Value]bool) (taintedParam int, changed bool)
propogate backward until find the source it may find a value, or a parameter in case of parameter, we need to propogate back to callee via ContextAware analysis
func BlockDominees ¶
func BlockDominees(context *Context, bb *ssa.BasicBlock, branch bool) (dominees []*ssa.BasicBlock)
Find the control flow dominees of a block branch: true if the dominees are the blocks that are dominated by the true branch of the if statement
func BranchDominees ¶
func BranchDominees(context *Context, bb *ssa.BasicBlock) (trueDominees, falseDominees []*ssa.BasicBlock)
func ContextAwareFunctionAnalysis ¶
func ContextAwareFunctionAnalysis(context *Context, value ssa.Value, callInst ssa.CallInstruction, callGraph *callgraph.Graph, taintedSet map[ssa.Value]bool, valueFieldMap map[ssa.Value]*FieldSet, callStack *CallStack) (end bool, taintedArgs []ssa.Value, taintedRets []ssa.Value)
only taint the callsite returns if the taint hits k8s client call, if taintedSet is updated
Params: @value is the source of the taint @callInst is the call instruction
TODO: XXX Do backward propogation for tainted parameters
func Dominators ¶
Dominators finds the dominees of the fields, and store the relationship into the context.FieldToFieldDominees map
func DumpKnownFunctions ¶
func DumpKnownFunctions()
func FindAllUses ¶
func FindAllUses(context *Context)
func FindDefaultAssignment ¶
func FindDirectBranches ¶
func FindFunctionDominees ¶
func FindFunctionDominees(context *Context, bbs []*ssa.BasicBlock) (dominees []*ssa.Function)
naive way to find function dominees it only find the direct function dominees, does not propogate it also does not consider functions called at different place but with the same conditions
func FindUsesInBlocks ¶
func FindUsesInBlocks(context *Context, blocks []*ssa.BasicBlock, frontierValuesByBlock map[*ssa.BasicBlock]*[]ssa.Value) map[ssa.Value]bool
func FindUsesInConditions ¶
func GetCopyOverFields ¶
func GetDefaultValue ¶
func GetFieldToK8sMapping ¶
func GetTypeTree ¶
func GetTypeTreeHelper ¶
func GetTypeTreeHelper(context *Context, seedType types.Type, node *TypeFieldNode)
func GetValueToFieldMappingPass ¶
func GetValueToFieldMappingPass(context *Context, prog *ssa.Program, seedType *string, seedPkgPath *string) (map[ssa.Value]*FieldSet, map[ssa.Value]bool)
Forward pass Introduction:
- all values of type seedType
Propogation rule:
- Call: to the specific parameter of the callee
- ChangeInterface
- ChangeType
- Convert
- Field: propogate with field name
- FieldAddr: propogate with field name
- Index: propogate with index
- IndexAddr: propogate with index
- MakeInterface
- LookUp: TODO if used as X, propogate
- Phi: propogate with merged paths
- UnOp: propogate if dereference
- Store: TODO propogate backward
- Return + Extract: TODO propogate to function callsites
Sink:
- Stop at all other instruction types
- Stop propogation when calling library functions
Frontier values:
- if all a value's all referrers are propogated, it's not frontier
func GlobalAssignments ¶
func GlobalAssignments(global *ssa.Global) (ret []ssa.Instruction)
Returns store instructions that store some value into the global variable in the package init function
func HandleStructField ¶
func HandleStructField(context *Context, originalTaintedStructValue *TaintedStructValue) (ret map[ssa.Value]bool)
func IsInterfaceFunctionSink ¶
func IsK8sInterfaceFunction ¶
func IsK8sStaticFunction ¶
func IsKubernetesType ¶
func IsStaticFunctionSink ¶
func PropagateToCallee ¶
func PropogateToCallee ¶
func PropogateToConditions ¶
func ReachableBlocks ¶
func ReachableBlocks(context *Context, bb *ssa.BasicBlock, stop *ssa.BasicBlock) (reachSet map[*ssa.BasicBlock]bool)
func StructFieldPropagateToCallee ¶
func StructFieldPropagateToCallee(context *Context, worklist *[]*TaintedStructValue, callee *ssa.Function, taintedStructValue *TaintedStructValue, callSiteTaintedArgIndexSet []int)
func TaintAnalysisPass ¶
func TaintAnalysisPass(context *Context, prog *ssa.Program, frontierValues map[ssa.Value]bool, valueFieldMap map[ssa.Value]*FieldSet) *FieldSet
Alloc BinOp Call ChangeInterface ChangeType Convert DebugRef Defer Extract Field FieldAddr Go If Index IndexAddr Jump Lookup MakeChan MakeClosure MakeInterface MakeMap MakeSlice MapUpdate Next Panic Phi Range Return RunDefers Select Send Slice SliceToArrayPointer Store TypeAssert UnOp
func TaintFunction ¶
func TaintFunction(context *Context, functionBody *ssa.Function, entryPoints []ssa.Value, callGraph *callgraph.Graph, valueFieldMap map[ssa.Value]*FieldSet, callStack *CallStack) (end bool, taintedParams []int, taintedRets []int)
XXX: May also need to taint the receiver
TaintFunction tries to run taint analysis on the functionBody The initial taints are specified in the returns the indices of the tainted return values
func TaintK8sFromValue ¶
func TaintK8sFromValue(context *Context, value ssa.Value, originalValue ssa.Value, valueFieldMap map[ssa.Value]*FieldSet, callGraph *callgraph.Graph, backCallStack *CallStack, fromArg bool) bool
returns true if value taints k8s API calls
Types ¶
type BranchCondition ¶
type CallStack ¶
type CallStack []FunctionCall
func NewCallStack ¶
func NewCallStack() *CallStack
func (*CallStack) Contain ¶
func (cs *CallStack) Contain(call FunctionCall) bool
func (*CallStack) Pop ¶
func (cs *CallStack) Pop() (FunctionCall, bool)
func (*CallStack) Push ¶
func (cs *CallStack) Push(call FunctionCall)
type ConcreteCondition ¶
func (*ConcreteCondition) Encode ¶
func (c *ConcreteCondition) Encode() string
func (*ConcreteCondition) String ¶
func (c *ConcreteCondition) String() string
func (*ConcreteCondition) ToPlainCondition ¶
func (c *ConcreteCondition) ToPlainCondition() *PlainCondition
type ConcreteConditionSet ¶
type ConcreteConditionSet struct {
ConcreteConditionGroups map[string]*ConditionGroup
}
func NewConcreteConditionSet ¶
func NewConcreteConditionSet() *ConcreteConditionSet
func (*ConcreteConditionSet) Add ¶
func (ccs *ConcreteConditionSet) Add(cg *ConditionGroup)
func (*ConcreteConditionSet) Contain ¶
func (ccs *ConcreteConditionSet) Contain(cc string) bool
func (*ConcreteConditionSet) Extend ¶
func (ccs *ConcreteConditionSet) Extend(cgList ...*ConditionGroup)
func (*ConcreteConditionSet) Intersect ¶
func (ccs *ConcreteConditionSet) Intersect(ccs_ *ConcreteConditionSet) *ConcreteConditionSet
func (*ConcreteConditionSet) ToPlainConditionSet ¶
func (ccs *ConcreteConditionSet) ToPlainConditionSet(path []string) *PlainConcreteConditionSet
type ConditionGroup ¶
type ConditionGroup struct { Typ ConditionGroupType ConcreteConditions []*ConcreteCondition }
func (*ConditionGroup) Encode ¶
func (cg *ConditionGroup) Encode() string
func (*ConditionGroup) String ¶
func (cg *ConditionGroup) String() string
func (*ConditionGroup) ToPlainCondition ¶
func (cg *ConditionGroup) ToPlainCondition() *PlainConditionGroup
type ConditionGroupType ¶
type ConditionGroupType string
const ( AndConditionGroup ConditionGroupType = "AND" OrConditionGroup ConditionGroupType = "OR" )
type Context ¶
type Context struct { Program *ssa.Program MainPackages []*ssa.Package RootModule *packages.Module CallGraph *callgraph.Graph PostDominators map[*ssa.Function]*PostDominator FieldDataDependencyMap map[string]*util.FieldSet // map's key's value depends on value FieldTree *FieldNode ValueToFieldNodeSetMap ValueToFieldNodeSetMap ValueFieldMap map[ssa.Value]*util.FieldSet FieldToValueMap map[string]*[]ssa.Value StoreInsts []ssa.Instruction AppendCalls []ssa.Instruction DefaultValueMap map[ssa.Value]*ssa.Const IfToCondition map[ssa.Instruction]*BranchCondition BranchValueDominees map[ssa.Instruction]*UsesInBranch DomineeToConditions map[string]*ConcreteConditionSet FieldToK8sMapping map[*TypeFieldNode]FieldInKubernetes }
type FieldInKubernetes ¶
type FieldInKubernetes struct { KubernetesType types.Type `json:"kubernetes_type"` FieldPath string `json:"fieldPath"` }
func (FieldInKubernetes) MarshalJSON ¶
func (f FieldInKubernetes) MarshalJSON() ([]byte, error)
type FieldInKubernetesSlice ¶
type FieldInKubernetesSlice []FieldInKubernetes
type FieldNode ¶
type FieldNode struct { // A FieldNode represent a specific field in the CR struct ki.Node // the list of values that map to this field ValueSet map[ssa.Value]struct{} }
func NewFieldNode ¶
func NewFieldNode() *FieldNode
func (*FieldNode) EncodedPath ¶
func (*FieldNode) IndexFieldNode ¶
Returns the child with the "INDEX" field name, create one if not exist
type FieldNodeSet ¶
type FieldNodeSet map[*FieldNode]struct{}
type FunctionCall ¶
type FunctionTaintResult ¶
func GetKnownInterfaceFunction ¶
func GetKnownInterfaceFunction(functionCall FunctionCall) *FunctionTaintResult
func GetKnownStaticFunction ¶
func GetKnownStaticFunction(function *ssa.Function, callSiteTaintedParamIndexSet []int) *FunctionTaintResult
func (FunctionTaintResult) String ¶
func (r FunctionTaintResult) String() string
type PlainConcreteConditionSet ¶
type PlainConcreteConditionSet struct { Path []string `json:"path"` Typ ConditionGroupType `json:"type"` PlainConditionGroups []*PlainConditionGroup `json:"conditionGroups"` }
type PlainCondition ¶
type PlainCondition struct { Field []string `json:"field"` Op string `json:"op"` Value string `json:"value"` }
same as ConcreteCondition, but json friendly
type PlainConditionGroup ¶
type PlainConditionGroup struct { Typ ConditionGroupType `json:"type"` ConcreteConditions []*PlainCondition `json:"conditions"` }
type PostDominator ¶
func NewPostDominator ¶
func NewPostDominator(fn *ssa.Function) *PostDominator
func (*PostDominator) Dominate ¶
func (pd *PostDominator) Dominate(b1 *ssa.BasicBlock, b2 *ssa.BasicBlock) bool
func (*PostDominator) Print ¶
func (pd *PostDominator) Print()
func (*PostDominator) String ¶
func (pd *PostDominator) String() string
type PropogatedValue ¶
type ReferredInstruction ¶
type ReferredInstruction struct { Instruction ssa.Instruction Value ssa.Value }
Represent a uniqle taint candidate
type TaintedStructValue ¶
type TypeFieldNode ¶
type TypeFieldNode struct { // A FieldNode represent a specific field in the CR struct ki.Node // the list of values that map to this field ValueSet map[ssa.Value]struct{} Type types.Type TagName string }
func NewTypeFieldNode ¶
func NewTypeFieldNode(tagName string, typ types.Type) *TypeFieldNode
func (*TypeFieldNode) AddValue ¶
func (fn *TypeFieldNode) AddValue(value ssa.Value)
func (*TypeFieldNode) EncodedPath ¶
func (fn *TypeFieldNode) EncodedPath() string
func (*TypeFieldNode) IsMetadata ¶
func (fn *TypeFieldNode) IsMetadata() bool
func (*TypeFieldNode) IsObjectMeta ¶
func (fn *TypeFieldNode) IsObjectMeta() bool
func (*TypeFieldNode) IsStatus ¶
func (fn *TypeFieldNode) IsStatus() bool
type TypeFieldNodeSet ¶
type TypeFieldNodeSet map[*TypeFieldNode]struct{}
func NewTypeFieldNodeSet ¶
func NewTypeFieldNodeSet() TypeFieldNodeSet
func (TypeFieldNodeSet) Add ¶
func (set TypeFieldNodeSet) Add(node *TypeFieldNode)
func (TypeFieldNodeSet) Contains ¶
func (set TypeFieldNodeSet) Contains(node *TypeFieldNode) bool
func (TypeFieldNodeSet) IsMetadata ¶
func (set TypeFieldNodeSet) IsMetadata() bool
func (TypeFieldNodeSet) IsObjectMeta ¶
func (set TypeFieldNodeSet) IsObjectMeta() bool
func (TypeFieldNodeSet) IsStatus ¶
func (set TypeFieldNodeSet) IsStatus() bool
func (TypeFieldNodeSet) Path ¶
func (set TypeFieldNodeSet) Path() string
type ValueToFieldNodeSetMap ¶
type ValueToFieldNodeSetMap map[ssa.Value]FieldNodeSet