aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/subsystem/extractor.go
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2023-03-28 15:03:50 +0200
committerAleksandr Nogikh <wp32pw@gmail.com>2023-03-28 18:07:01 +0200
commitfc067f05bce8156101e90f93fe87e702114b863f (patch)
treef230df37293dd7afc370eec1eba5521e60ebd1df /pkg/subsystem/extractor.go
parent5232cf0254feea67f22bebab12e4302bb37f74f6 (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.go27
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 {