Documentation ¶
Overview ¶
Package config provides a simple way to manage configuration files.
Use Load(filename) to load a configuration from a specific filename.
Use SetGlobalConfig(filename) to set filename as the global config, and then LoadGlobal() to load the global config.
A config file should be in yaml format. The top-level fields can be any of the fields defined in the Config struct type. The other fields are defined by the types of the fields of Config and nested struct types. For example, a valid config file is as follows:
sinks: - package: fmt method: Printf sources: - method: Read
Identifying code elements ¶
The config uses CodeIdentifier to identify specific code entities. For example, sinks and sources are CodeIdentifiers which identifies specific functions in specific packages, or types, etc.. An important feature of the code identifiers is that the string specifications are seen as regexes if they can be compiled to regexes, otherwise they are strings.
Index ¶
- Constants
- Variables
- func ExistsCid(a []CodeIdentifier, f func(identifier CodeIdentifier) bool) bool
- func ParseXMLConfigFormat(c *Config, b []byte) error
- func SetGlobalConfig(filename string)
- type CodeIdentifier
- type Config
- func (c Config) ExceedsMaxDepth(d int) bool
- func (c Config) IsSomeBacktracePoint(cid CodeIdentifier) bool
- func (c Config) IsSomeSanitizer(cid CodeIdentifier) bool
- func (c Config) IsSomeSink(cid CodeIdentifier) bool
- func (c Config) IsSomeSource(cid CodeIdentifier) bool
- func (c Config) IsSomeValidator(cid CodeIdentifier) bool
- func (c Config) MatchCoverageFilter(filename string) bool
- func (c Config) MatchPkgFilter(pkgname string) bool
- func (c Config) RelPath(filename string) string
- func (c Config) ReportNoCalleeFile() string
- func (c Config) Verbose() bool
- type EscapeConfig
- type LogGroup
- func (l *LogGroup) Debugf(format string, v ...any)
- func (l *LogGroup) Errorf(format string, v ...any)
- func (l *LogGroup) GetDebug() *log.Logger
- func (l *LogGroup) GetError() *log.Logger
- func (l *LogGroup) Infof(format string, v ...any)
- func (l *LogGroup) LogsDebug() bool
- func (l *LogGroup) LogsError() bool
- func (l *LogGroup) LogsInfo() bool
- func (l *LogGroup) LogsTrace() bool
- func (l *LogGroup) LogsWarning() bool
- func (l *LogGroup) SetAllFlags(x int)
- func (l *LogGroup) SetAllOutput(w io.Writer)
- func (l *LogGroup) SetError(w io.Writer)
- func (l *LogGroup) Tracef(format string, v ...any)
- func (l *LogGroup) Warnf(format string, v ...any)
- type LogLevel
- type MxFile
- type Object
- type Options
- type SlicingSpec
- type StaticCommandsSpec
- type TaintSpec
Constants ¶
const ( // EscapeBehaviorSummarize specifies that the function should be summarized in the escape analysis EscapeBehaviorSummarize = "summarize" // EscapeBehaviorNoop specifies that the function is a noop in the escape analysis EscapeBehaviorNoop = "noop" // EscapeBehaviorUnknown specifies that the function is "unknown" in the escape analysis EscapeBehaviorUnknown = "unknown" )
Variables ¶
var DefaultMaxCallDepth = -1
DefaultMaxCallDepth is the default maximum call stack value that will be considered by the analyses using it -1 means that depth limit is ignored
Functions ¶
func ExistsCid ¶
func ExistsCid(a []CodeIdentifier, f func(identifier CodeIdentifier) bool) bool
ExistsCid is true if there is some x in a such that f(x) is true. O(len(a))
func ParseXMLConfigFormat ¶
ParseXMLConfigFormat parses the bytes as xml, expecting a drawio file representing a diagram of dataflow problems where the options of the config are specified in the metadata.
func SetGlobalConfig ¶
func SetGlobalConfig(filename string)
SetGlobalConfig sets the global config filename
Types ¶
type CodeIdentifier ¶
type CodeIdentifier struct { // Context stores an additional string that can be used depending on context by analyses. Typically, one can use // Context to match the parent function name when matching a code identifier. Context string `xml:"context,attr"` // Package identifies the package of the code identifier. Package string `xml:"package,attr"` // in drawio input, package is an attribute // Interface identifies the interface name of the code identifier. Interface string `xml:"interface,attr"` // Package identifies the method/function of the code identifier. Method is used loosely here to mean function // or actual method Method string `xml:"method,attr"` // Receiver identified the receiver object of a method call Receiver string `xml:"receiver,attr"` // Field identifies a specific field Field string `xml:"field,attr"` // Type identifies a specific type, which can be used for example to identify allocation of a given type Type string `xml:"type,attr"` // Label can be used to store user-defined information about the code identifier. Label string `xml:"label,attr"` // Kind can be used to give additional semantic meaning to the code identifier. For example, it can be used // to tag a code identifier as a specific "channel receive" Kind string `xml:"kind,attr"` // contains filtered or unexported fields }
A CodeIdentifier identifies a code element that is a source, sink, sanitizer, etc.. A code identifier can be identified from its package, method, receiver, field or type, or any combination of those This is meant to replicate functionality in go-flow-levee and gokart, and can be extended as needed
func NewCodeIdentifier ¶
func NewCodeIdentifier(cid CodeIdentifier) CodeIdentifier
NewCodeIdentifier properly intializes cid.
func (*CodeIdentifier) FullMethodName ¶
func (cid *CodeIdentifier) FullMethodName() string
FullMethodName returns the fully qualified name of the code identifier.
func (*CodeIdentifier) MatchInterface ¶
func (cid *CodeIdentifier) MatchInterface(f *ssa.Function) bool
MatchInterface matches a function to a code identifier by looking whether that function implements an interface's method, and using that method information to match against the code identifier
func (*CodeIdentifier) MatchPackageAndMethod ¶
func (cid *CodeIdentifier) MatchPackageAndMethod(f *ssa.Function) bool
MatchPackageAndMethod checks whether the function f matches the code identifier on the package and method fields. It is safe to call with nil values.
type Config ¶
type Config struct { Options // DataFlowSpecs is a path to a json file that contains the data flows specs for the interfaces in the dataflow // analyses DataflowSpecs []string `yaml:"dataflow-specs" json:"dataflow-specs"` EscapeConfig *EscapeConfig // TaintTrackingProblems lists the taint tracking specifications TaintTrackingProblems []TaintSpec `yaml:"taint-tracking-problems" json:"taint-tracking-problems"` // SlicingProblems lists the program slicing specifications SlicingProblems []SlicingSpec `yaml:"slicing-problems" json:"slicing-problems"` // StaticCommandsProblems lists the static commands problems StaticCommandsProblems []StaticCommandsSpec `yaml:"static-commands-problems" json:"static-commands-problems"` // contains filtered or unexported fields }
Config contains lists of sanitizers, sinks, sources, static commands to identify ... To add elements to a config file, add fields to this struct. If some field is not defined in the config file, it will be empty/zero in the struct. private fields are not populated from a yaml file, but computed after initialization
func LoadGlobal ¶
LoadGlobal loads the config file that has been set by SetGlobalConfig
func (Config) ExceedsMaxDepth ¶
ExceedsMaxDepth returns true if the input exceeds the maximum depth parameter of the configuration. (this implements the logic for using maximum depth; if the configuration setting is < 0, then this returns false)
func (Config) IsSomeBacktracePoint ¶
func (c Config) IsSomeBacktracePoint(cid CodeIdentifier) bool
IsSomeBacktracePoint returns true if the code identifier matches any backtrace point in the slicing problems
func (Config) IsSomeSanitizer ¶
func (c Config) IsSomeSanitizer(cid CodeIdentifier) bool
IsSomeSanitizer returns true if the code identifier matches any sanitizer in the config
func (Config) IsSomeSink ¶
func (c Config) IsSomeSink(cid CodeIdentifier) bool
IsSomeSink returns true if the code identifier matches any sink in the config
func (Config) IsSomeSource ¶
func (c Config) IsSomeSource(cid CodeIdentifier) bool
IsSomeSource returns true if the code identifier matches any source in the config
func (Config) IsSomeValidator ¶
func (c Config) IsSomeValidator(cid CodeIdentifier) bool
IsSomeValidator returns true if the code identifier matches any validator in the config
func (Config) MatchCoverageFilter ¶
MatchCoverageFilter returns true if the file name matches the coverageFilterRegex, if specified
func (Config) MatchPkgFilter ¶
MatchPkgFilter returns true if the package name pkgname matches the package filter set in the config file. If no package filter has been set in the config file, the regex will match anything and return true. This function safely considers the case where a filter has been specified by the user, but it could not be compiled to a regex. The safe case is to check whether the package filter string is a prefix of the pkgname
func (Config) ReportNoCalleeFile ¶
ReportNoCalleeFile return the file name that will contain the list of locations that have no callee
type EscapeConfig ¶
type EscapeConfig struct { // Functions controls behavior override, keyed by .String() (e.g. command-line-arguments.main, // (*package.Type).Method, etc). A value of "summarize" means process normally, "unknown" is // treat as unanalyzed, and "noop" means calls are assumed to have no escape effect (and return // nil if they have a pointer-like return). Functions map[string]string `json:"functions"` // The maximum size of an escape summary. If a function attempts to compute a larger summary, it // will be replaced by a conservative, unsummarized stub. SummaryMaximumSize int `json:"summary-maximum-size"` // Allow/blocklist of packages, keyed by package path. A value of true means allow, false is // block, and not present is default behavior. PkgFilter string `json:"pkg-filter"` // contains filtered or unexported fields }
EscapeConfig holds the options relative to the escape analysis configuration
func NewEscapeConfig ¶
func NewEscapeConfig() *EscapeConfig
NewEscapeConfig returns a new escape config with a preset summary maximum size and initialized Functions map.
func (*EscapeConfig) MatchPkgFilter ¶
func (c *EscapeConfig) MatchPkgFilter(pkgname string) bool
MatchPkgFilter matches a package name against a configuration. Returns true if the package name matches the filter.
type LogGroup ¶
type LogGroup struct { Level LogLevel // contains filtered or unexported fields }
LogGroup holds a set of loggers that will be called depending on the logging kind
func NewLogGroup ¶
NewLogGroup returns a log group that is configured to the logging settings stored inside the config
func (*LogGroup) Debugf ¶
Debugf calls Debug.Printf to print to the trace logger. Arguments are handled in the manner of Printf
func (*LogGroup) Errorf ¶
Errorf calls Error.Printf to print to the trace logger. Arguments are handled in the manner of Printf
func (*LogGroup) GetDebug ¶
GetDebug returns the debug level logger, for applications that need a logger as input
func (*LogGroup) GetError ¶
GetError returns the error logger, for applications that need a logger as input
func (*LogGroup) Infof ¶
Infof calls Info.Printf to print to the trace logger. Arguments are handled in the manner of Printf
func (*LogGroup) LogsError ¶
LogsError returns true if the log group logs error messages. Note that this is the lowest logging level, and if this returns false, it implies that the log group does not log anything.
func (*LogGroup) LogsWarning ¶
LogsWarning returns true if the log group logs warning messages
func (*LogGroup) SetAllFlags ¶
SetAllFlags sets the flag of all loggers in the log group to the argument provided
func (*LogGroup) SetAllOutput ¶
SetAllOutput sets all the output writers to the writer provided
type LogLevel ¶
type LogLevel int
LogLevel represents a logging level
const ( // ErrLevel =1 - the minimum level of logging. ErrLevel LogLevel = iota + 1 // WarnLevel =2 - the level for logging warnings, and errors WarnLevel // InfoLevel =3 - the level for logging high-level information, results InfoLevel // DebugLevel =4 - the level for debugging information. The tool will run properly on large programs with // that level of debug information. DebugLevel // TraceLevel =5 - the level for tracing. The tool will not run properly on large programs with that level // of information, but this is useful on smaller testing programs. TraceLevel )
type MxFile ¶
type MxFile struct { Object []Object `xml:"diagram>mxGraphModel>root>object"` Cells []mxCell `xml:"diagram>mxGraphModel>root>mxCell"` Modified string `xml:"modified,attr"` Host string `xml:"host,attr"` }
MxFile is the toplevel file representation in a draio diagram
type Object ¶
type Object struct { ID string `xml:"id,attr"` CodeIdentifier Options Forbidden bool `xml:"forbidden,attr"` Cell mxCell `xml:"mxCell"` IsSource bool `xml:"taint-source,attr"` IsSink bool `xml:"taint-sink,attr"` IsSanitizer bool `xml:"taint-sanitizer,attr"` IsValidator bool `xml:"taint-validator,attr"` DataflowSpecs string `xml:"dataflow-specs,attr"` Filters string `xml:"filters,attr"` }
Object represents an object in the drawio diagram
type Options ¶
type Options struct { // ReportsDir is the directory where all the reports will be stored. If the yaml config file this config struct has // been loaded does not specify a ReportsDir but sets any Report* option to true, then ReportsDir will be created // in the folder the binary is called. ReportsDir string `xml:"reports-dir,attr" yaml:"reports-dir" json:"reports-dir"` // PkgFilter is a filter for the taint analysis to build summaries only for the function whose package match the // prefix PkgFilter string `xml:"pkg-filter,attr" yaml:"pkg-filter" json:"pkg-filter"` // Run and use the escape analysis for analyses that have the option to use the escape analysis results. UseEscapeAnalysis bool `xml:"use-escape-analysis,attr" yaml:"use-escape-analysis" json:"use-escape-analysis"` // Path to a JSON file that has the escape configuration (allow/blocklist) EscapeConfigFile string `xml:"escape-config,attr" yaml:"escape-config" json:"escape-config"` // SkipInterprocedural can be set to true to skip the interprocedural (inter-procedural analysis) step SkipInterprocedural bool `xml:"skip-interprocedural,attr" yaml:"skip-interprocedural" json:"skip-interprocedural"` // CoverageFilter can be used to filter which packages will be reported in the coverage. If non-empty, // coverage will only for those packages that match CoverageFilter CoverageFilter string `xml:"coverage-filter,attr" yaml:"coverage-filter" json:"coverage-filter"` // ReportSummaries can be set to true, in which case summaries will be reported in a file names summaries-*.out in // the reports directory ReportSummaries bool `xml:"report-summaries,attr" yaml:"report-summaries" json:"report-summaries"` // SummarizeOnDemand specifies whether the graph should build summaries on-demand instead of all at once SummarizeOnDemand bool `xml:"summarize-on-demand,attr" yaml:"summarize-on-demand" json:"summarize-on-demand"` // IgnoreNonSummarized allows the analysis to ignore when the summary of a function has not been built in the first // analysis phase. This is only for experimentation, since the results may be unsound. // This has no effect when SummarizeOnDemand is true IgnoreNonSummarized bool `xml:"ignoreNonSummarized,attr" yaml:"ignore-non-summarized" json:"ignore-non-summarized"` // SourceTaintsArgs specifies whether calls to a source function also taints the argument. This is usually not // the case, but might be useful for some users or for source functions that do not return anything. SourceTaintsArgs bool `xml:"source-taints-args,attr" yaml:"source-taints-args" json:"source-taints-args"` // ReportPaths specifies whether the taint flows should be reported in separate files. For each taint flow, a new // file named taint-*.out will be generated with the trace from source to sink ReportPaths bool `xml:"report-paths,attr" yaml:"report-paths" json:"report-paths"` // ReportCoverage specifies whether coverage should be reported. If true, then a file names coverage-*.out will // be created in the report directory, containing the coverage data generated by the analysis ReportCoverage bool `xml:"report-coverage,attr" yaml:"report-coverage" json:"report-coverage"` // ReportNoCalleeSites specifies whether the tool should report where it does not find any callee. ReportNoCalleeSites bool `xml:"report-no-callee-sites,attr" yaml:"report-no-callee-sites" json:"report-no-callee-sites"` // MaxDepth sets a limit for the number of function call depth explored during the analysis // Default is -1. // If provided MaxDepth is <= 0, then it is ignored. MaxDepth int `xml:"max-depth,attr" yaml:"max-depth" json:"max-depth"` // PathSensitive is a boolean indicating whether the analysis should be run with access path sensitivity on // (will change to include more filtering in the future) // Note that the configuration option name is "field-sensitive" because this is the name that will be more // recognizable for users. PathSensitive bool `xml:"field-sensitive" yaml:"field-sensitive" json:"field-sensitive"` // MaxAlarms sets a limit for the number of alarms reported by an analysis. If MaxAlarms > 0, then at most // MaxAlarms will be reported. Otherwise, if MaxAlarms <= 0, it is ignored. MaxAlarms int `xml:"max-alarms,attr" yaml:"max-alarms" json:"max-alarms"` // Loglevel controls the verbosity of the tool LogLevel int `xml:"log-level,attr" yaml:"log-level" json:"log-level"` // Suppress warnings SilenceWarn bool `xml:"silence-warn,attr" json:"silence-warn" yaml:"silence-warn"` }
Options holds the global options for analyses
type SlicingSpec ¶
type SlicingSpec struct { // BacktracePoints is the list of identifiers to be considered as entrypoint functions for the backwards // dataflow analysis. BacktracePoints []CodeIdentifier // Filters contains a list of filters that can be used by analyses Filters []CodeIdentifier }
SlicingSpec contains code identifiers that identify a specific program slicing / backwards dataflow analysis spec.
func (SlicingSpec) IsBacktracePoint ¶
func (ss SlicingSpec) IsBacktracePoint(cid CodeIdentifier) bool
IsBacktracePoint returns true if the code identifier matches a backtrace point according to the SlicingSpec
type StaticCommandsSpec ¶
type StaticCommandsSpec struct { // StaticCommands is the list of identifiers to be considered as command execution for the static commands analysis // (not used) StaticCommands []CodeIdentifier `yaml:"static-commands" json:"static-commands"` }
StaticCommandsSpec contains code identifiers for the problem of identifying which commands are static
func (StaticCommandsSpec) IsStaticCommand ¶
func (scs StaticCommandsSpec) IsStaticCommand(cid CodeIdentifier) bool
IsStaticCommand returns true if the code identifier matches a static command specification in the config file
type TaintSpec ¶
type TaintSpec struct { // Sanitizers is the list of sanitizers for the taint analysis Sanitizers []CodeIdentifier // Validators is the list of validators for the dataflow analyses Validators []CodeIdentifier // Sinks is the list of sinks for the taint analysis Sinks []CodeIdentifier // Sources is the list of sources for the taint analysis Sources []CodeIdentifier // Filters contains a list of filters that can be used by analyses Filters []CodeIdentifier // ExplicitFlowOnly indicates whether the taint analysis should only consider explicit data flows. // This should be set to true when proving a data flow property instead of an information flow property. ExplicitFlowOnly bool `yaml:"explicit-flow-only" json:"explicit-flow-only"` }
TaintSpec contains code identifiers that identify a specific taint tracking problem
func (TaintSpec) IsSanitizer ¶
func (ts TaintSpec) IsSanitizer(cid CodeIdentifier) bool
IsSanitizer returns true if the code identifier matches a sanitizer specification in the config file
func (TaintSpec) IsSink ¶
func (ts TaintSpec) IsSink(cid CodeIdentifier) bool
IsSink returns true if the code identifier matches a sink specification in the config file
func (TaintSpec) IsSource ¶
func (ts TaintSpec) IsSource(cid CodeIdentifier) bool
IsSource returns true if the code identifier matches a source specification in the config file
func (TaintSpec) IsValidator ¶
func (ts TaintSpec) IsValidator(cid CodeIdentifier) bool
IsValidator returns true if the code identifier matches a validator specification in the config file