public static PropertySetAnalysisContext Create(
     AbstractValueDomain <PropertySetAbstractValue> valueDomain,
     WellKnownTypeProvider wellKnownTypeProvider,
     ControlFlowGraph controlFlowGraph,
     ISymbol owningSymbol,
     InterproceduralAnalysisConfiguration interproceduralAnalysisConfig,
     bool pessimisticAnalysis,
     PointsToAnalysisResult pointsToAnalysisResult,
     ValueContentAnalysisResult valueContentAnalysisResultOpt,
     Func <PropertySetAnalysisContext, PropertySetAnalysisResult> getOrComputeAnalysisResult,
     string typeToTrackMetadataName,
     ConstructorMapper constructorMapper,
     PropertyMapperCollection propertyMappers,
     HazardousUsageEvaluatorCollection hazardousUsageEvaluators)
 {
     return(new PropertySetAnalysisContext(
                valueDomain,
                wellKnownTypeProvider,
                controlFlowGraph,
                owningSymbol,
                interproceduralAnalysisConfig,
                pessimisticAnalysis,
                pointsToAnalysisResult,
                valueContentAnalysisResultOpt,
                getOrComputeAnalysisResult,
                parentControlFlowGraphOpt: null,
                interproceduralAnalysisDataOpt: null,
                typeToTrackMetadataName: typeToTrackMetadataName,
                constructorMapper: constructorMapper,
                propertyMappers: propertyMappers,
                hazardousUsageEvaluators: hazardousUsageEvaluators,
                hazardousUsageTypesToNames: hazardousUsageEvaluators.GetTypeToNameMapping(wellKnownTypeProvider)));
 }
예제 #2
0
 private PropertySetAnalysisContext(
     AbstractValueDomain <PropertySetAbstractValue> valueDomain,
     WellKnownTypeProvider wellKnownTypeProvider,
     ControlFlowGraph controlFlowGraph,
     ISymbol owningSymbol,
     InterproceduralAnalysisConfiguration interproceduralAnalysisConfig,
     bool pessimisticAnalysis,
     PointsToAnalysisResult pointsToAnalysisResult,
     ValueContentAnalysisResult valueContentAnalysisResultOpt,
     Func <PropertySetAnalysisContext, PropertySetAnalysisResult> getOrComputeAnalysisResult,
     ControlFlowGraph parentControlFlowGraphOpt,
     InterproceduralPropertySetAnalysisData interproceduralAnalysisDataOpt,
     string typeToTrackMetadataName,
     ConstructorMapper constructorMapper,
     PropertyMapperCollection propertyMappers,
     HazardousUsageEvaluatorCollection hazardousUsageEvaluators,
     ImmutableDictionary <INamedTypeSymbol, string> hazardousUsageTypesToNames)
     : base(valueDomain, wellKnownTypeProvider, controlFlowGraph, owningSymbol, interproceduralAnalysisConfig, pessimisticAnalysis,
            predicateAnalysis: false, exceptionPathsAnalysis: false, copyAnalysisResultOpt: null, pointsToAnalysisResult,
            getOrComputeAnalysisResult, parentControlFlowGraphOpt, interproceduralAnalysisDataOpt, interproceduralAnalysisPredicateOpt: null)
 {
     this.ValueContentAnalysisResultOpt = valueContentAnalysisResultOpt;
     this.TypeToTrackMetadataName       = typeToTrackMetadataName;
     this.ConstructorMapper             = constructorMapper;
     this.PropertyMappers            = propertyMappers;
     this.HazardousUsageEvaluators   = hazardousUsageEvaluators;
     this.HazardousUsageTypesToNames = hazardousUsageTypesToNames;
 }
        public override PropertySetAnalysisContext ForkForInterproceduralAnalysis(
            IMethodSymbol invokedMethod,
            ControlFlowGraph invokedCfg,
            IOperation operation,
            PointsToAnalysisResult pointsToAnalysisResultOpt,
            CopyAnalysisResult copyAnalysisResultOpt,
            ValueContentAnalysisResult valueContentAnalysisResultOpt,
            InterproceduralPropertySetAnalysisData interproceduralAnalysisData)
        {
            Debug.Assert(pointsToAnalysisResultOpt != null);
            Debug.Assert(copyAnalysisResultOpt == null);

            return(new PropertySetAnalysisContext(
                       ValueDomain,
                       WellKnownTypeProvider,
                       invokedCfg,
                       invokedMethod,
                       InterproceduralAnalysisConfiguration,
                       PessimisticAnalysis,
                       pointsToAnalysisResultOpt,
                       valueContentAnalysisResultOpt,
                       GetOrComputeAnalysisResult,
                       ControlFlowGraph,
                       interproceduralAnalysisData,
                       this.TypeToTrackMetadataName,
                       this.ConstructorMapper,
                       this.PropertyMappers,
                       this.HazardousUsageEvaluators,
                       this.HazardousUsageTypesToNames));
        }
예제 #4
0
 public abstract TAnalysisContext ForkForInterproceduralAnalysis(
     IMethodSymbol invokedMethod,
     ControlFlowGraph invokedCfg,
     IOperation operation,
     PointsToAnalysisResult pointsToAnalysisResultOpt,
     CopyAnalysisResult copyAnalysisResultOpt,
     ValueContentAnalysisResult valueContentAnalysisResultOpt,
     InterproceduralAnalysisData <TAnalysisData, TAnalysisContext, TAbstractAnalysisValue> interproceduralAnalysisData);
예제 #5
0
        protected AbstractDataFlowAnalysisContext(
            AbstractValueDomain <TAbstractAnalysisValue> valueDomain,
            WellKnownTypeProvider wellKnownTypeProvider,
            ControlFlowGraph controlFlowGraph,
            ISymbol owningSymbol,
            AnalyzerOptions analyzerOptions,
            InterproceduralAnalysisConfiguration interproceduralAnalysisConfig,
            bool pessimisticAnalysis,
            bool predicateAnalysis,
            bool exceptionPathsAnalysis,
            CopyAnalysisResult copyAnalysisResultOpt,
            PointsToAnalysisResult pointsToAnalysisResultOpt,
            ValueContentAnalysisResult valueContentAnalysisResultOpt,
            Func <TAnalysisContext, TAnalysisResult> tryGetOrComputeAnalysisResult,
            ControlFlowGraph parentControlFlowGraphOpt,
            InterproceduralAnalysisData <TAnalysisData, TAnalysisContext, TAbstractAnalysisValue> interproceduralAnalysisDataOpt,
            InterproceduralAnalysisPredicate interproceduralAnalysisPredicateOpt)
        {
            Debug.Assert(valueDomain != null, "valueDomain must not be null for use in ComputeHashCodeParts");
            Debug.Assert(controlFlowGraph != null);
            Debug.Assert(owningSymbol != null);
            Debug.Assert(owningSymbol.Kind == SymbolKind.Method ||
                         owningSymbol.Kind == SymbolKind.Field ||
                         owningSymbol.Kind == SymbolKind.Property ||
                         owningSymbol.Kind == SymbolKind.Event);
            Debug.Assert(Equals(owningSymbol.OriginalDefinition, owningSymbol));
            Debug.Assert(wellKnownTypeProvider != null);
            Debug.Assert(tryGetOrComputeAnalysisResult != null);
            Debug.Assert(pointsToAnalysisResultOpt == null ||
                         pointsToAnalysisResultOpt.ControlFlowGraph == controlFlowGraph);
            Debug.Assert(copyAnalysisResultOpt == null ||
                         copyAnalysisResultOpt.ControlFlowGraph == controlFlowGraph);
            Debug.Assert(valueContentAnalysisResultOpt == null ||
                         valueContentAnalysisResultOpt.ControlFlowGraph == controlFlowGraph);

            ValueDomain                          = valueDomain;
            WellKnownTypeProvider                = wellKnownTypeProvider;
            ControlFlowGraph                     = controlFlowGraph;
            ParentControlFlowGraphOpt            = parentControlFlowGraphOpt;
            OwningSymbol                         = owningSymbol;
            AnalyzerOptions                      = analyzerOptions;
            InterproceduralAnalysisConfiguration = interproceduralAnalysisConfig;
            PessimisticAnalysis                  = pessimisticAnalysis;
            PredicateAnalysis                    = predicateAnalysis;
            ExceptionPathsAnalysis               = exceptionPathsAnalysis;
            CopyAnalysisResultOpt                = copyAnalysisResultOpt;
            PointsToAnalysisResultOpt            = pointsToAnalysisResultOpt;
            ValueContentAnalysisResultOpt        = valueContentAnalysisResultOpt;
            TryGetOrComputeAnalysisResult        = tryGetOrComputeAnalysisResult;
            InterproceduralAnalysisDataOpt       = interproceduralAnalysisDataOpt;
            InterproceduralAnalysisPredicateOpt  = interproceduralAnalysisPredicateOpt;
        }
예제 #6
0
 public override CopyAnalysisContext ForkForInterproceduralAnalysis(
     IMethodSymbol invokedMethod,
     ControlFlowGraph invokedControlFlowGraph,
     IOperation operation,
     PointsToAnalysisResult pointsToAnalysisResultOpt,
     CopyAnalysisResult copyAnalysisResultOpt,
     ValueContentAnalysisResult valueContentAnalysisResultOpt,
     InterproceduralCopyAnalysisData interproceduralAnalysisData)
 {
     return(new CopyAnalysisContext(ValueDomain, WellKnownTypeProvider, invokedControlFlowGraph, invokedMethod, AnalyzerOptions, InterproceduralAnalysisConfiguration,
                                    PessimisticAnalysis, ExceptionPathsAnalysis, pointsToAnalysisResultOpt, TryGetOrComputeAnalysisResult, ControlFlowGraph, interproceduralAnalysisData,
                                    InterproceduralAnalysisPredicateOpt));
 }
 protected sealed override void ComputeHashCodeParts(ref RoslynHashCode hashCode)
 {
     hashCode.Add(ValueDomain.GetHashCode());
     hashCode.Add(OwningSymbol.GetHashCode());
     hashCode.Add(ControlFlowGraph.GetHashCode());
     hashCode.Add(AnalyzerOptions.GetHashCode());
     hashCode.Add(InterproceduralAnalysisConfiguration.GetHashCode());
     hashCode.Add(PessimisticAnalysis.GetHashCode());
     hashCode.Add(PredicateAnalysis.GetHashCode());
     hashCode.Add(ExceptionPathsAnalysis.GetHashCode());
     hashCode.Add(CopyAnalysisResult.GetHashCodeOrDefault());
     hashCode.Add(PointsToAnalysisResult.GetHashCodeOrDefault());
     hashCode.Add(ValueContentAnalysisResult.GetHashCodeOrDefault());
     hashCode.Add(InterproceduralAnalysisData.GetHashCodeOrDefault());
     hashCode.Add(InterproceduralAnalysisPredicate.GetHashCodeOrDefault());
     ComputeHashCodePartsSpecific(ref hashCode);
 }
예제 #8
0
 protected sealed override void ComputeHashCodeParts(Action <int> addPart)
 {
     addPart(ValueDomain.GetHashCode());
     addPart(OwningSymbol.GetHashCode());
     addPart(ControlFlowGraph.GetHashCode());
     addPart(AnalyzerOptions.GetHashCode());
     addPart(InterproceduralAnalysisConfiguration.GetHashCode());
     addPart(PessimisticAnalysis.GetHashCode());
     addPart(PredicateAnalysis.GetHashCode());
     addPart(ExceptionPathsAnalysis.GetHashCode());
     addPart(CopyAnalysisResult.GetHashCodeOrDefault());
     addPart(PointsToAnalysisResult.GetHashCodeOrDefault());
     addPart(ValueContentAnalysisResult.GetHashCodeOrDefault());
     addPart(InterproceduralAnalysisData.GetHashCodeOrDefault());
     addPart(InterproceduralAnalysisPredicate.GetHashCodeOrDefault());
     ComputeHashCodePartsSpecific(addPart);
 }
        public override DisposeAnalysisContext ForkForInterproceduralAnalysis(
            IMethodSymbol invokedMethod,
            ControlFlowGraph invokedControlFlowGraph,
            IOperation operation,
            PointsToAnalysisResult pointsToAnalysisResultOpt,
            CopyAnalysisResult copyAnalysisResultOpt,
            ValueContentAnalysisResult valueContentAnalysisResultOpt,
            InterproceduralDisposeAnalysisData interproceduralAnalysisData)
        {
            Debug.Assert(pointsToAnalysisResultOpt != null);
            Debug.Assert(copyAnalysisResultOpt == null);
            Debug.Assert(valueContentAnalysisResultOpt == null);

            return(new DisposeAnalysisContext(ValueDomain, WellKnownTypeProvider, invokedControlFlowGraph, invokedMethod, InterproceduralAnalysisConfiguration, PessimisticAnalysis,
                                              ExceptionPathsAnalysis, pointsToAnalysisResultOpt, TryGetOrComputeAnalysisResult, DisposeOwnershipTransferLikelyTypes, DisposeOwnershipTransferAtConstructor,
                                              DisposeOwnershipTransferAtMethodCall, TrackInstanceFields, ControlFlowGraph, interproceduralAnalysisData, InterproceduralAnalysisPredicateOpt));
        }
 private PropertySetAnalysisContext(
     AbstractValueDomain <PropertySetAbstractValue> valueDomain,
     WellKnownTypeProvider wellKnownTypeProvider,
     ControlFlowGraph controlFlowGraph,
     ISymbol owningSymbol,
     AnalyzerOptions analyzerOptions,
     InterproceduralAnalysisConfiguration interproceduralAnalysisConfig,
     bool pessimisticAnalysis,
     PointsToAnalysisResult pointsToAnalysisResult,
     ValueContentAnalysisResult valueContentAnalysisResultOpt,
     Func <PropertySetAnalysisContext, PropertySetAnalysisResult> tryGetOrComputeAnalysisResult,
     ControlFlowGraph parentControlFlowGraphOpt,
     InterproceduralPropertySetAnalysisData interproceduralAnalysisDataOpt,
     ImmutableHashSet <string> typeToTrackMetadataNames,
     ConstructorMapper constructorMapper,
     PropertyMapperCollection propertyMappers,
     HazardousUsageEvaluatorCollection hazardousUsageEvaluators,
     ImmutableDictionary <(INamedTypeSymbol, bool), string> hazardousUsageTypesToNames)
        protected sealed override bool ComputeEqualsByHashCodeParts(CacheBasedEquatable <TAnalysisContext> obj)
        {
            var other = (AbstractDataFlowAnalysisContext <TAnalysisData, TAnalysisContext, TAnalysisResult, TAbstractAnalysisValue>)obj;

            return(ValueDomain.GetHashCode() == other.ValueDomain.GetHashCode() &&
                   OwningSymbol.GetHashCode() == other.OwningSymbol.GetHashCode() &&
                   ControlFlowGraph.GetHashCode() == other.ControlFlowGraph.GetHashCode() &&
                   AnalyzerOptions.GetHashCode() == other.AnalyzerOptions.GetHashCode() &&
                   InterproceduralAnalysisConfiguration.GetHashCode() == other.InterproceduralAnalysisConfiguration.GetHashCode() &&
                   PessimisticAnalysis.GetHashCode() == other.PessimisticAnalysis.GetHashCode() &&
                   PredicateAnalysis.GetHashCode() == other.PredicateAnalysis.GetHashCode() &&
                   ExceptionPathsAnalysis.GetHashCode() == other.ExceptionPathsAnalysis.GetHashCode() &&
                   CopyAnalysisResult.GetHashCodeOrDefault() == other.CopyAnalysisResult.GetHashCodeOrDefault() &&
                   PointsToAnalysisResult.GetHashCodeOrDefault() == other.PointsToAnalysisResult.GetHashCodeOrDefault() &&
                   ValueContentAnalysisResult.GetHashCodeOrDefault() == other.ValueContentAnalysisResult.GetHashCodeOrDefault() &&
                   InterproceduralAnalysisData.GetHashCodeOrDefault() == other.InterproceduralAnalysisData.GetHashCodeOrDefault() &&
                   InterproceduralAnalysisPredicate.GetHashCodeOrDefault() == other.InterproceduralAnalysisPredicate.GetHashCodeOrDefault() &&
                   ComputeEqualsByHashCodeParts(other));
        }
예제 #12
0
        public override ParameterValidationAnalysisContext ForkForInterproceduralAnalysis(
            IMethodSymbol invokedMethod,
            ControlFlowGraph invokedCfg,
            IOperation operation,
            PointsToAnalysisResult pointsToAnalysisResultOpt,
            CopyAnalysisResult copyAnalysisResultOpt,
            ValueContentAnalysisResult valueContentAnalysisResultOpt,
            InterproceduralParameterValidationAnalysisData interproceduralAnalysisData)
        {
            Debug.Assert(pointsToAnalysisResultOpt != null);
            Debug.Assert(copyAnalysisResultOpt == null);
            Debug.Assert(valueContentAnalysisResultOpt == null);

            // Do not invoke any interprocedural analysis more than one level down.
            // We only care about analyzing validation methods.
            return(new ParameterValidationAnalysisContext(
                       ValueDomain, WellKnownTypeProvider, invokedCfg, invokedMethod, InterproceduralAnalysisConfiguration,
                       PessimisticAnalysis, pointsToAnalysisResultOpt, GetOrComputeAnalysisResult, ControlFlowGraph,
                       interproceduralAnalysisData, TrackHazardousParameterUsages));
        }
예제 #13
0
        private TaintedDataAnalysisContext(
            AbstractValueDomain <TaintedDataAbstractValue> valueDomain,
            WellKnownTypeProvider wellKnownTypeProvider,
            ControlFlowGraph controlFlowGraph,
            ISymbol owningSymbol,
            AnalyzerOptions analyzerOptions,
            InterproceduralAnalysisConfiguration interproceduralAnalysisConfig,
            bool pessimisticAnalysis,
            CopyAnalysisResult copyAnalysisResultOpt,
            PointsToAnalysisResult pointsToAnalysisResult,
            ValueContentAnalysisResult valueContentAnalysisResult,
            Func <TaintedDataAnalysisContext, TaintedDataAnalysisResult> tryGetOrComputeAnalysisResult,
            ControlFlowGraph parentControlFlowGraph,
            InterproceduralTaintedDataAnalysisData interproceduralAnalysisDataOpt,
            TaintedDataSymbolMap <SourceInfo> taintedSourceInfos,
            TaintedDataSymbolMap <SanitizerInfo> taintedSanitizerInfos,
            TaintedDataSymbolMap <SinkInfo> taintedSinkInfos)
            : base(
                valueDomain,
                wellKnownTypeProvider,
                controlFlowGraph,
                owningSymbol,
                analyzerOptions,
                interproceduralAnalysisConfig,
                pessimisticAnalysis,
                predicateAnalysis: false,
                exceptionPathsAnalysis: false,
                copyAnalysisResultOpt,
                pointsToAnalysisResult,
                valueContentAnalysisResult,
                tryGetOrComputeAnalysisResult,
                parentControlFlowGraph,
                interproceduralAnalysisDataOpt,
                interproceduralAnalysisPredicateOpt: null)
        {
            Debug.Assert(pointsToAnalysisResult != null);

            this.SourceInfos    = taintedSourceInfos ?? throw new ArgumentNullException(nameof(taintedSourceInfos));
            this.SanitizerInfos = taintedSanitizerInfos ?? throw new ArgumentNullException(nameof(taintedSanitizerInfos));
            this.SinkInfos      = taintedSinkInfos ?? throw new ArgumentNullException(nameof(taintedSinkInfos));
        }
예제 #14
0
        public static TaintedDataAnalysisContext Create(
            AbstractValueDomain <TaintedDataAbstractValue> valueDomain,
            WellKnownTypeProvider wellKnownTypeProvider,
            ControlFlowGraph controlFlowGraph,
            ISymbol owningSymbol,
            AnalyzerOptions analyzerOptions,
            InterproceduralAnalysisConfiguration interproceduralAnalysisConfig,
            bool pessimisticAnalysis,
            CopyAnalysisResult copyAnalysisResultOpt,
            PointsToAnalysisResult pointsToAnalysisResult,
            ValueContentAnalysisResult valueContentAnalysisResult,
            Func <TaintedDataAnalysisContext, TaintedDataAnalysisResult> tryGetOrComputeAnalysisResult,
            TaintedDataSymbolMap <SourceInfo> taintedSourceInfos,
            TaintedDataSymbolMap <SanitizerInfo> taintedSanitizerInfos,
            TaintedDataSymbolMap <SinkInfo> taintedSinkInfos)
        {
            Debug.Assert(pointsToAnalysisResult != null);

            return(new TaintedDataAnalysisContext(
                       valueDomain,
                       wellKnownTypeProvider,
                       controlFlowGraph,
                       owningSymbol,
                       analyzerOptions,
                       interproceduralAnalysisConfig,
                       pessimisticAnalysis,
                       copyAnalysisResultOpt,
                       pointsToAnalysisResult,
                       valueContentAnalysisResult,
                       tryGetOrComputeAnalysisResult,
                       parentControlFlowGraph: null,
                       interproceduralAnalysisDataOpt: null,
                       taintedSourceInfos: taintedSourceInfos,
                       taintedSanitizerInfos: taintedSanitizerInfos,
                       taintedSinkInfos: taintedSinkInfos));
        }
예제 #15
0
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);

            context.RegisterCompilationStartAction(
                (CompilationStartAnalysisContext compilationContext) =>
            {
                Compilation compilation             = compilationContext.Compilation;
                TaintedDataConfig taintedDataConfig = TaintedDataConfig.GetOrCreate(compilation);
                TaintedDataSymbolMap <SourceInfo> sourceInfoSymbolMap = taintedDataConfig.GetSourceSymbolMap(this.SinkKind);
                if (sourceInfoSymbolMap.IsEmpty)
                {
                    return;
                }

                TaintedDataSymbolMap <SinkInfo> sinkInfoSymbolMap = taintedDataConfig.GetSinkSymbolMap(this.SinkKind);
                if (sinkInfoSymbolMap.IsEmpty)
                {
                    return;
                }

                compilationContext.RegisterOperationBlockStartAction(
                    operationBlockStartContext =>
                {
                    ISymbol owningSymbol                = operationBlockStartContext.OwningSymbol;
                    AnalyzerOptions options             = operationBlockStartContext.Options;
                    CancellationToken cancellationToken = operationBlockStartContext.CancellationToken;
                    if (owningSymbol.IsConfiguredToSkipAnalysis(options, TaintedDataEnteringSinkDescriptor, compilation, cancellationToken))
                    {
                        return;
                    }

                    WellKnownTypeProvider wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilation);
                    InterproceduralAnalysisConfiguration interproceduralAnalysisConfiguration = InterproceduralAnalysisConfiguration.Create(
                        options,
                        SupportedDiagnostics,
                        defaultInterproceduralAnalysisKind: InterproceduralAnalysisKind.ContextSensitive,
                        cancellationToken: cancellationToken);
                    Lazy <ControlFlowGraph> controlFlowGraphFactory = new Lazy <ControlFlowGraph>(
                        () => operationBlockStartContext.OperationBlocks.GetControlFlowGraph());
                    Lazy <PointsToAnalysisResult> pointsToFactory = new Lazy <PointsToAnalysisResult>(
                        () =>
                    {
                        if (controlFlowGraphFactory.Value == null)
                        {
                            return(null);
                        }

                        return(PointsToAnalysis.TryGetOrComputeResult(
                                   controlFlowGraphFactory.Value,
                                   owningSymbol,
                                   options,
                                   wellKnownTypeProvider,
                                   interproceduralAnalysisConfiguration,
                                   interproceduralAnalysisPredicateOpt: null));
                    });
                    Lazy <(PointsToAnalysisResult, ValueContentAnalysisResult)> valueContentFactory = new Lazy <(PointsToAnalysisResult, ValueContentAnalysisResult)>(
                        () =>
                    {
                        if (controlFlowGraphFactory.Value == null)
                        {
                            return(null, null);
                        }

                        ValueContentAnalysisResult valuecontentAnalysisResult = ValueContentAnalysis.TryGetOrComputeResult(
                            controlFlowGraphFactory.Value,
                            owningSymbol,
                            options,
                            wellKnownTypeProvider,
                            interproceduralAnalysisConfiguration,
                            out _,
                            out PointsToAnalysisResult p);

                        return(p, valuecontentAnalysisResult);
                    });

                    PooledHashSet <IOperation> rootOperationsNeedingAnalysis = PooledHashSet <IOperation> .GetInstance();

                    operationBlockStartContext.RegisterOperationAction(
                        operationAnalysisContext =>
                    {
                        IPropertyReferenceOperation propertyReferenceOperation = (IPropertyReferenceOperation)operationAnalysisContext.Operation;
                        if (sourceInfoSymbolMap.IsSourceProperty(propertyReferenceOperation.Property))
                        {
                            lock (rootOperationsNeedingAnalysis)
                            {
                                rootOperationsNeedingAnalysis.Add(propertyReferenceOperation.GetRoot());
                            }
                        }
                    },
                        OperationKind.PropertyReference);

                    operationBlockStartContext.RegisterOperationAction(
                        operationAnalysisContext =>
                    {
                        IInvocationOperation invocationOperation = (IInvocationOperation)operationAnalysisContext.Operation;
                        if (sourceInfoSymbolMap.IsSourceMethod(
                                invocationOperation.TargetMethod,
                                invocationOperation.Arguments,
                                pointsToFactory,
                                valueContentFactory,
                                out _))
                        {
                            lock (rootOperationsNeedingAnalysis)
                            {
                                rootOperationsNeedingAnalysis.Add(invocationOperation.GetRoot());
                            }
                        }
                    },
                        OperationKind.Invocation);

                    if (taintedDataConfig.HasTaintArraySource(SinkKind))
                    {
                        operationBlockStartContext.RegisterOperationAction(
                            operationAnalysisContext =>
                        {
                            IArrayInitializerOperation arrayInitializerOperation = (IArrayInitializerOperation)operationAnalysisContext.Operation;
                            if (arrayInitializerOperation.GetAncestor <IArrayCreationOperation>(OperationKind.ArrayCreation)?.Type is IArrayTypeSymbol arrayTypeSymbol &&
                                sourceInfoSymbolMap.IsSourceConstantArrayOfType(arrayTypeSymbol))
                            {
                                lock (rootOperationsNeedingAnalysis)
                                {
                                    rootOperationsNeedingAnalysis.Add(operationAnalysisContext.Operation.GetRoot());
                                }
                            }
                        },
                            OperationKind.ArrayInitializer);
                    }

                    operationBlockStartContext.RegisterOperationBlockEndAction(
                        operationBlockAnalysisContext =>
                    {
                        try
                        {
                            lock (rootOperationsNeedingAnalysis)
                            {
                                if (!rootOperationsNeedingAnalysis.Any())
                                {
                                    return;
                                }

                                if (controlFlowGraphFactory.Value == null)
                                {
                                    return;
                                }

                                foreach (IOperation rootOperation in rootOperationsNeedingAnalysis)
                                {
                                    TaintedDataAnalysisResult taintedDataAnalysisResult = TaintedDataAnalysis.TryGetOrComputeResult(
                                        controlFlowGraphFactory.Value,
                                        operationBlockAnalysisContext.Compilation,
                                        operationBlockAnalysisContext.OwningSymbol,
                                        operationBlockAnalysisContext.Options,
                                        TaintedDataEnteringSinkDescriptor,
                                        sourceInfoSymbolMap,
                                        taintedDataConfig.GetSanitizerSymbolMap(this.SinkKind),
                                        sinkInfoSymbolMap,
                                        operationBlockAnalysisContext.CancellationToken);
                                    if (taintedDataAnalysisResult == null)
                                    {
                                        return;
                                    }

                                    foreach (TaintedDataSourceSink sourceSink in taintedDataAnalysisResult.TaintedDataSourceSinks)
                                    {
                                        if (!sourceSink.SinkKinds.Contains(this.SinkKind))
                                        {
                                            continue;
                                        }

                                        foreach (SymbolAccess sourceOrigin in sourceSink.SourceOrigins)
                                        {
                                            // Something like:
                                            // CA3001: Potential SQL injection vulnerability was found where '{0}' in method '{1}' may be tainted by user-controlled data from '{2}' in method '{3}'.
                                            Diagnostic diagnostic = Diagnostic.Create(
                                                this.TaintedDataEnteringSinkDescriptor,
                                                sourceSink.Sink.Location,
                                                additionalLocations: new Location[] { sourceOrigin.Location },
                                                messageArgs: new object[] {
                                                sourceSink.Sink.Symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                                sourceSink.Sink.AccessingMethod.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                                sourceOrigin.Symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                                sourceOrigin.AccessingMethod.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)
                                            });
                                            operationBlockAnalysisContext.ReportDiagnostic(diagnostic);
                                        }
                                    }
                                }
                            }
                        }
                        finally
                        {
                            rootOperationsNeedingAnalysis.Free();
                        }
                    });
                });
            });
        }
예제 #16
0
        private static TaintedDataAnalysisResult TryGetOrComputeResult(
            ControlFlowGraph cfg,
            Compilation compilation,
            ISymbol containingMethod,
            AnalyzerOptions analyzerOptions,
            TaintedDataSymbolMap <SourceInfo> taintedSourceInfos,
            TaintedDataSymbolMap <SanitizerInfo> taintedSanitizerInfos,
            TaintedDataSymbolMap <SinkInfo> taintedSinkInfos,
            InterproceduralAnalysisConfiguration interproceduralAnalysisConfig)
        {
            if (cfg == null)
            {
                Debug.Fail("Expected non-null CFG");
                return(null);
            }

            WellKnownTypeProvider      wellKnownTypeProvider      = WellKnownTypeProvider.GetOrCreate(compilation);
            ValueContentAnalysisResult valueContentAnalysisResult = null;
            CopyAnalysisResult         copyAnalysisResult         = null;
            PointsToAnalysisResult     pointsToAnalysisResult     = null;

            if (taintedSourceInfos.RequiresValueContentAnalysis || taintedSanitizerInfos.RequiresValueContentAnalysis || taintedSinkInfos.RequiresValueContentAnalysis)
            {
                valueContentAnalysisResult = ValueContentAnalysis.TryGetOrComputeResult(
                    cfg,
                    containingMethod,
                    analyzerOptions,
                    wellKnownTypeProvider,
                    interproceduralAnalysisConfig,
                    out copyAnalysisResult,
                    out pointsToAnalysisResult,
                    pessimisticAnalysis: true,
                    performCopyAnalysis: false);
                if (valueContentAnalysisResult == null)
                {
                    return(null);
                }
            }
            else
            {
                pointsToAnalysisResult = PointsToAnalysis.TryGetOrComputeResult(
                    cfg,
                    containingMethod,
                    analyzerOptions,
                    wellKnownTypeProvider,
                    interproceduralAnalysisConfig,
                    interproceduralAnalysisPredicateOpt: null,
                    pessimisticAnalysis: true,
                    performCopyAnalysis: false);
                if (pointsToAnalysisResult == null)
                {
                    return(null);
                }
            }

            TaintedDataAnalysisContext analysisContext = TaintedDataAnalysisContext.Create(
                TaintedDataAbstractValueDomain.Default,
                wellKnownTypeProvider,
                cfg,
                containingMethod,
                analyzerOptions,
                interproceduralAnalysisConfig,
                pessimisticAnalysis: false,
                copyAnalysisResultOpt: copyAnalysisResult,
                pointsToAnalysisResult: pointsToAnalysisResult,
                valueContentAnalysisResult: valueContentAnalysisResult,
                tryGetOrComputeAnalysisResult: TryGetOrComputeResultForAnalysisContext,
                taintedSourceInfos: taintedSourceInfos,
                taintedSanitizerInfos: taintedSanitizerInfos,
                taintedSinkInfos: taintedSinkInfos);

            return(TryGetOrComputeResultForAnalysisContext(analysisContext));
        }
예제 #17
0
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);

            context.RegisterCompilationStartAction(
                (CompilationStartAnalysisContext compilationContext) =>
            {
                TaintedDataConfig taintedDataConfig = TaintedDataConfig.GetOrCreate(compilationContext.Compilation);
                TaintedDataSymbolMap <SourceInfo> sourceInfoSymbolMap = taintedDataConfig.GetSourceSymbolMap(this.SinkKind);
                if (sourceInfoSymbolMap.IsEmpty)
                {
                    return;
                }

                TaintedDataSymbolMap <SinkInfo> sinkInfoSymbolMap = taintedDataConfig.GetSinkSymbolMap(this.SinkKind);
                if (sinkInfoSymbolMap.IsEmpty)
                {
                    return;
                }

                compilationContext.RegisterOperationBlockStartAction(
                    operationBlockStartContext =>
                {
                    ISymbol owningSymbol = operationBlockStartContext.OwningSymbol;
                    if (owningSymbol.IsConfiguredToSkipAnalysis(operationBlockStartContext.Options,
                                                                TaintedDataEnteringSinkDescriptor, operationBlockStartContext.Compilation, operationBlockStartContext.CancellationToken))
                    {
                        return;
                    }

                    PooledHashSet <IOperation> rootOperationsNeedingAnalysis = PooledHashSet <IOperation> .GetInstance();

                    operationBlockStartContext.RegisterOperationAction(
                        operationAnalysisContext =>
                    {
                        IPropertyReferenceOperation propertyReferenceOperation = (IPropertyReferenceOperation)operationAnalysisContext.Operation;
                        IOperation rootOperation = operationAnalysisContext.Operation.GetRoot();
                        if (sourceInfoSymbolMap.IsSourceProperty(propertyReferenceOperation.Property))
                        {
                            lock (rootOperationsNeedingAnalysis)
                            {
                                rootOperationsNeedingAnalysis.Add(rootOperation);
                            }
                        }
                    },
                        OperationKind.PropertyReference);

                    operationBlockStartContext.RegisterOperationAction(
                        operationAnalysisContext =>
                    {
                        IInvocationOperation invocationOperation = (IInvocationOperation)operationAnalysisContext.Operation;
                        IOperation rootOperation = operationAnalysisContext.Operation.GetRoot();
                        PooledDictionary <PointsToCheck, ImmutableHashSet <string> > evaluateWithPointsToAnalysis         = null;
                        PooledDictionary <ValueContentCheck, ImmutableHashSet <string> > evaluateWithValueContentAnalysis = null;
                        PointsToAnalysisResult pointsToAnalysisResult         = null;
                        ValueContentAnalysisResult valueContentAnalysisResult = null;
                        if (rootOperation.TryGetEnclosingControlFlowGraph(out ControlFlowGraph cfg))
                        {
                            pointsToAnalysisResult = PointsToAnalysis.TryGetOrComputeResult(
                                cfg,
                                owningSymbol,
                                operationAnalysisContext.Options,
                                WellKnownTypeProvider.GetOrCreate(operationAnalysisContext.Compilation),
                                InterproceduralAnalysisConfiguration.Create(
                                    operationAnalysisContext.Options,
                                    SupportedDiagnostics,
                                    defaultInterproceduralAnalysisKind: InterproceduralAnalysisKind.ContextSensitive,
                                    cancellationToken: operationAnalysisContext.CancellationToken),
                                interproceduralAnalysisPredicateOpt: null);
                            if (pointsToAnalysisResult == null)
                            {
                                return;
                            }
                        }

                        if (sourceInfoSymbolMap.RequiresValueContentAnalysis)
                        {
                            valueContentAnalysisResult = ValueContentAnalysis.TryGetOrComputeResult(
                                cfg,
                                owningSymbol,
                                operationAnalysisContext.Options,
                                WellKnownTypeProvider.GetOrCreate(operationAnalysisContext.Compilation),
                                InterproceduralAnalysisConfiguration.Create(
                                    operationAnalysisContext.Options,
                                    SupportedDiagnostics,
                                    defaultInterproceduralAnalysisKind: InterproceduralAnalysisKind.ContextSensitive,
                                    cancellationToken: operationAnalysisContext.CancellationToken),
                                out var copyAnalysisResult,
                                out pointsToAnalysisResult);
                            if (valueContentAnalysisResult == null)
                            {
                                return;
                            }
                        }

                        try
                        {
                            if (sourceInfoSymbolMap.IsSourceMethod(
                                    invocationOperation.TargetMethod,
                                    invocationOperation.Arguments,
                                    invocationOperation.Arguments.Select(o => pointsToAnalysisResult[o.Kind, o.Syntax]).ToImmutableArray(),
                                    invocationOperation.Arguments.Select(o => valueContentAnalysisResult[o.Kind, o.Syntax]).ToImmutableArray(),
                                    out _))
                            {
                                lock (rootOperationsNeedingAnalysis)
                                {
                                    rootOperationsNeedingAnalysis.Add(rootOperation);
                                }
                            }
                        }
                        finally
                        {
                            evaluateWithPointsToAnalysis?.Free();
                            evaluateWithValueContentAnalysis?.Free();
                        }
                    },
                        OperationKind.Invocation);

                    if (taintedDataConfig.HasTaintArraySource(SinkKind))
                    {
                        operationBlockStartContext.RegisterOperationAction(
                            operationAnalysisContext =>
                        {
                            IArrayInitializerOperation arrayInitializerOperation = (IArrayInitializerOperation)operationAnalysisContext.Operation;
                            if (arrayInitializerOperation.GetAncestor <IArrayCreationOperation>(OperationKind.ArrayCreation)?.Type is IArrayTypeSymbol arrayTypeSymbol &&
                                sourceInfoSymbolMap.IsSourceConstantArrayOfType(arrayTypeSymbol))
                            {
                                lock (rootOperationsNeedingAnalysis)
                                {
                                    rootOperationsNeedingAnalysis.Add(operationAnalysisContext.Operation.GetRoot());
                                }
                            }
                        },
                            OperationKind.ArrayInitializer);
                    }

                    operationBlockStartContext.RegisterOperationBlockEndAction(
                        operationBlockAnalysisContext =>
                    {
                        try
                        {
                            lock (rootOperationsNeedingAnalysis)
                            {
                                if (!rootOperationsNeedingAnalysis.Any())
                                {
                                    return;
                                }

                                foreach (IOperation rootOperation in rootOperationsNeedingAnalysis)
                                {
                                    if (!rootOperation.TryGetEnclosingControlFlowGraph(out var cfg))
                                    {
                                        continue;
                                    }

                                    TaintedDataAnalysisResult taintedDataAnalysisResult = TaintedDataAnalysis.TryGetOrComputeResult(
                                        cfg,
                                        operationBlockAnalysisContext.Compilation,
                                        operationBlockAnalysisContext.OwningSymbol,
                                        operationBlockAnalysisContext.Options,
                                        TaintedDataEnteringSinkDescriptor,
                                        sourceInfoSymbolMap,
                                        taintedDataConfig.GetSanitizerSymbolMap(this.SinkKind),
                                        sinkInfoSymbolMap,
                                        operationBlockAnalysisContext.CancellationToken);
                                    if (taintedDataAnalysisResult == null)
                                    {
                                        return;
                                    }

                                    foreach (TaintedDataSourceSink sourceSink in taintedDataAnalysisResult.TaintedDataSourceSinks)
                                    {
                                        if (!sourceSink.SinkKinds.Contains(this.SinkKind))
                                        {
                                            continue;
                                        }

                                        foreach (SymbolAccess sourceOrigin in sourceSink.SourceOrigins)
                                        {
                                            // Something like:
                                            // CA3001: Potential SQL injection vulnerability was found where '{0}' in method '{1}' may be tainted by user-controlled data from '{2}' in method '{3}'.
                                            Diagnostic diagnostic = Diagnostic.Create(
                                                this.TaintedDataEnteringSinkDescriptor,
                                                sourceSink.Sink.Location,
                                                additionalLocations: new Location[] { sourceOrigin.Location },
                                                messageArgs: new object[] {
                                                sourceSink.Sink.Symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                                sourceSink.Sink.AccessingMethod.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                                sourceOrigin.Symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                                sourceOrigin.AccessingMethod.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)
                                            });
                                            operationBlockAnalysisContext.ReportDiagnostic(diagnostic);
                                        }
                                    }
                                }
                            }
                        }
                        finally
                        {
                            rootOperationsNeedingAnalysis.Free();
                        }
                    });
                });
            });
        }