diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2024-10-24 10:22:25 +0200 |
|---|---|---|
| committer | Taras Madan <tarasmadan@google.com> | 2024-10-25 12:08:02 +0000 |
| commit | 9a199dec544ca9f1560a7352d0d003cf9206d8c5 (patch) | |
| tree | 589d3c30946513dc5d1349d781ef82b67dcd4279 /pkg/mgrconfig | |
| parent | 479141f703a43adab07cba7f8b3c99399fbbeb68 (diff) | |
pkg/mgrconfig, syz-manager: support focus areas
Switch from the CoverageFilter to the more flexible mechanism of focus
areas.
Diffstat (limited to 'pkg/mgrconfig')
| -rw-r--r-- | pkg/mgrconfig/config.go | 39 | ||||
| -rw-r--r-- | pkg/mgrconfig/load.go | 38 |
2 files changed, 69 insertions, 8 deletions
diff --git a/pkg/mgrconfig/config.go b/pkg/mgrconfig/config.go index f4857e613..b475c4eed 100644 --- a/pkg/mgrconfig/config.go +++ b/pkg/mgrconfig/config.go @@ -144,14 +144,9 @@ type Config struct { // Use KCOV coverage (default: true). Cover bool `json:"cover"` - // Use coverage filter. Supported types of filter: - // "files": support specifying kernel source files, support regular expression. - // eg. "files": ["^net/core/tcp.c$", "^net/sctp/", "tcp"]. - // "functions": support specifying kernel functions, support regular expression. - // eg. "functions": ["^foo$", "^bar", "baz"]. - // "pcs": specify raw PC table files name. - // Each line of the file should be: "64-bit-pc:32-bit-weight\n". - // eg. "0xffffffff81000000:0x10\n" + + // CovFilter used to restrict the area of the kernel visible to syzkaller. + // DEPRECATED! Use the FocusAreas parameter instead. CovFilter CovFilterCfg `json:"cover_filter,omitempty"` // For each prog in the corpus, remember the raw array of PCs obtained from the kernel. @@ -235,6 +230,34 @@ type Experimental struct { // Use automatically (auto) generated or manually (manual) written descriptions or any (any) (default: manual) DescriptionsMode string `json:"descriptions_mode"` + + // FocusAreas configures what attention syzkaller should pay to the specific areas of the kernel. + // The probability of selecting a program from an area is at least `Weight / sum of weights`. + // If FocusAreas is non-empty, by default all kernel code not covered by any filter will be ignored. + // To focus fuzzing on some areas, but to consider the rest of the code as well, add a record + // with an empty Filter, but non-empty weight. + // E.g. "focus_areas": [ {"filter": {"files": ["^net"]}, "weight": 10.0}, {"weight": 1.0"} ]. + FocusAreas []FocusArea `json:"focus_areas,omitempty"` +} + +type FocusArea struct { + // Name allows to display detailed statistics for every focus area. + Name string `json:"name"` + + // A coverage filter. + // Supported filter types: + // "files": support specifying kernel source files, support regular expression. + // eg. "files": ["^net/core/tcp.c$", "^net/sctp/", "tcp"]. + // "functions": support specifying kernel functions, support regular expression. + // eg. "functions": ["^foo$", "^bar", "baz"]. + // "pcs": specify raw PC table files name. + // Each line of the file should be: "64-bit-pc:32-bit-weight\n". + // eg. "0xffffffff81000000:0x10\n" + // If empty, it's assumed to match the whole kernel. + Filter CovFilterCfg `json:"filter,omitempty"` + + // Weight is a positive number that determines how much focus should be put on this area. + Weight float64 `json:"weight"` } type Subsystem struct { diff --git a/pkg/mgrconfig/load.go b/pkg/mgrconfig/load.go index 792802e60..4529f8ec0 100644 --- a/pkg/mgrconfig/load.go +++ b/pkg/mgrconfig/load.go @@ -198,6 +198,9 @@ func Complete(cfg *Config) error { if err != nil { return err } + if err := cfg.completeFocusAreas(); err != nil { + return err + } cfg.initTimeouts() cfg.VMLess = cfg.Type == "none" return nil @@ -324,6 +327,41 @@ func (cfg *Config) completeBinaries() error { return nil } +func (cfg *Config) completeFocusAreas() error { + names := map[string]bool{} + seenEmptyFilter := false + for i, area := range cfg.Experimental.FocusAreas { + if area.Name != "" { + if names[area.Name] { + return fmt.Errorf("duplicate focus area name: %q", area.Name) + } + names[area.Name] = true + } + if area.Weight <= 0 { + return fmt.Errorf("focus area #%d: negative weight", i) + } + if area.Filter.Empty() { + if seenEmptyFilter { + return fmt.Errorf("there must be only one focus area with an empty filter") + } + seenEmptyFilter = true + } + } + if !cfg.CovFilter.Empty() { + if len(cfg.Experimental.FocusAreas) > 0 { + return fmt.Errorf("you cannot use both cov_filter and focus_areas") + } + cfg.Experimental.FocusAreas = []FocusArea{ + { + Name: "filtered", + Filter: cfg.CovFilter, + Weight: 1.0, + }, + } + } + return nil +} + func splitTarget(target string) (string, string, string, error) { if target == "" { return "", "", "", fmt.Errorf("target is empty") |
