diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2023-03-28 15:03:50 +0200 |
|---|---|---|
| committer | Aleksandr Nogikh <wp32pw@gmail.com> | 2023-03-28 18:07:01 +0200 |
| commit | fc067f05bce8156101e90f93fe87e702114b863f (patch) | |
| tree | f230df37293dd7afc370eec1eba5521e60ebd1df /pkg/subsystem/extractor.go | |
| parent | 5232cf0254feea67f22bebab12e4302bb37f74f6 (diff) | |
pkg/subsystem: disambiguate subsystems by reproducers
There are some minor subsystems (e.g. PAGE CACHE in Linux) that are
parts of several big subsystems. At the same time, a reproducer can
clearly disambiguate such case.
If subsystems from reproducers and subsystems from guilty files
intersect, only proceed with the results of the intersection.
Diffstat (limited to 'pkg/subsystem/extractor.go')
| -rw-r--r-- | pkg/subsystem/extractor.go | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/pkg/subsystem/extractor.go b/pkg/subsystem/extractor.go index 1f635c7b3..338b7a4fc 100644 --- a/pkg/subsystem/extractor.go +++ b/pkg/subsystem/extractor.go @@ -39,19 +39,38 @@ func (e *Extractor) Extract(crashes []*Crash) []*Subsystem { } // If all reproducers hint at the same subsystem, take it as well. - reproSubsystems := map[*Subsystem]int{} + reproCounts := map[*Subsystem]int{} + fromRepro := []*Subsystem{} for _, crash := range crashes { if len(crash.SyzRepro) == 0 { continue } for _, subsystem := range e.raw.FromProg(crash.SyzRepro) { - reproSubsystems[subsystem]++ - if reproSubsystems[subsystem] == reproCount { - subsystems = append(subsystems, subsystem) + reproCounts[subsystem]++ + if reproCounts[subsystem] == reproCount { + fromRepro = append(fromRepro, subsystem) } } } + // It can be the case that guilty paths point to several subsystems, but the reproducer + // can clearly point to one of them. + if len(fromRepro) > 0 { + newSubsystems := []*Subsystem{} + for _, reproSubsystem := range fromRepro { + parents := reproSubsystem.ReachableParents() + for _, subsystem := range subsystems { + if _, ok := parents[subsystem]; ok { + newSubsystems = append(newSubsystems, reproSubsystem) + break + } + } + } + if len(newSubsystems) > 0 { + subsystems = newSubsystems + } + } + // If there are both parents and children, remove parents. ignore := make(map[*Subsystem]struct{}) for _, entry := range subsystems { |
