From fc067f05bce8156101e90f93fe87e702114b863f Mon Sep 17 00:00:00 2001 From: Aleksandr Nogikh Date: Tue, 28 Mar 2023 15:03:50 +0200 Subject: 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. --- pkg/subsystem/extractor.go | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) (limited to 'pkg/subsystem/extractor.go') 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 { -- cgit mrf-deployment