config

package
v0.1.0-alpha.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 3, 2024 License: Apache-2.0 Imports: 15 Imported by: 0

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

View Source
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

View Source
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

func ParseXMLConfigFormat(c *Config, b []byte) error

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.

func (*CodeIdentifier) MatchType

func (cid *CodeIdentifier) MatchType(typ types.Type) bool

MatchType checks whether the code identifier matches the type represented as a types.Type. 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 Load

func Load(filename string) (*Config, error)

Load reads a configuration from a file

func LoadGlobal

func LoadGlobal() (*Config, error)

LoadGlobal loads the config file that has been set by SetGlobalConfig

func NewDefault

func NewDefault() *Config

NewDefault returns an empty default config.

func (Config) ExceedsMaxDepth

func (c Config) ExceedsMaxDepth(d int) bool

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

func (c Config) MatchCoverageFilter(filename string) bool

MatchCoverageFilter returns true if the file name matches the coverageFilterRegex, if specified

func (Config) MatchPkgFilter

func (c Config) MatchPkgFilter(pkgname string) bool

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) RelPath

func (c Config) RelPath(filename string) string

RelPath returns filename path relative to the config source file

func (Config) ReportNoCalleeFile

func (c Config) ReportNoCalleeFile() string

ReportNoCalleeFile return the file name that will contain the list of locations that have no callee

func (Config) Verbose

func (c Config) Verbose() bool

Verbose returns true is the configuration verbosity setting is larger than Info (i.e. Debug or Trace)

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

func NewLogGroup(config *Config) *LogGroup

NewLogGroup returns a log group that is configured to the logging settings stored inside the config

func (*LogGroup) Debugf

func (l *LogGroup) Debugf(format string, v ...any)

Debugf calls Debug.Printf to print to the trace logger. Arguments are handled in the manner of Printf

func (*LogGroup) Errorf

func (l *LogGroup) Errorf(format string, v ...any)

Errorf calls Error.Printf to print to the trace logger. Arguments are handled in the manner of Printf

func (*LogGroup) GetDebug

func (l *LogGroup) GetDebug() *log.Logger

GetDebug returns the debug level logger, for applications that need a logger as input

func (*LogGroup) GetError

func (l *LogGroup) GetError() *log.Logger

GetError returns the error logger, for applications that need a logger as input

func (*LogGroup) Infof

func (l *LogGroup) Infof(format string, v ...any)

Infof calls Info.Printf to print to the trace logger. Arguments are handled in the manner of Printf

func (*LogGroup) LogsDebug

func (l *LogGroup) LogsDebug() bool

LogsDebug returns true if the log group logs debug messages

func (*LogGroup) LogsError

func (l *LogGroup) LogsError() bool

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) LogsInfo

func (l *LogGroup) LogsInfo() bool

LogsInfo returns true if the log group logs info messages

func (*LogGroup) LogsTrace

func (l *LogGroup) LogsTrace() bool

LogsTrace returns true if the log group logs trace messages

func (*LogGroup) LogsWarning

func (l *LogGroup) LogsWarning() bool

LogsWarning returns true if the log group logs warning messages

func (*LogGroup) SetAllFlags

func (l *LogGroup) SetAllFlags(x int)

SetAllFlags sets the flag of all loggers in the log group to the argument provided

func (*LogGroup) SetAllOutput

func (l *LogGroup) SetAllOutput(w io.Writer)

SetAllOutput sets all the output writers to the writer provided

func (*LogGroup) SetError

func (l *LogGroup) SetError(w io.Writer)

SetError sets the output writer of the error logger

func (*LogGroup) Tracef

func (l *LogGroup) Tracef(format string, v ...any)

Tracef calls Trace.Printf to print to the trace logger. Arguments are handled in the manner of Printf

func (*LogGroup) Warnf

func (l *LogGroup) Warnf(format string, v ...any)

Warnf calls Warn.Printf to print to the trace logger. Arguments are handled in the manner of Printf

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

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL