diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2023-04-04 11:39:00 +0200 |
|---|---|---|
| committer | Aleksandr Nogikh <wp32pw@gmail.com> | 2023-04-04 13:39:20 +0200 |
| commit | 18e8a98274ea4160a7f7d4a0b207f31a8726a791 (patch) | |
| tree | 18976741a0e286a9bc5cfb6ddaea0d4094fddc28 /pkg | |
| parent | fd331b6d85b45e990c4037d3f6d76dbad0a69eb8 (diff) | |
pkg/subsystem: update the bug subsystem extraction logic
There was a small bug and, as a result, subsystems from reproducers
always superceded all other ones. That was not the desired side-effect.
Fix the logic and add a test to linux_test.go.
Diffstat (limited to 'pkg')
| -rw-r--r-- | pkg/subsystem/extractor.go | 36 | ||||
| -rw-r--r-- | pkg/subsystem/lists/linux_test.go | 19 |
2 files changed, 42 insertions, 13 deletions
diff --git a/pkg/subsystem/extractor.go b/pkg/subsystem/extractor.go index 338b7a4fc..996560a31 100644 --- a/pkg/subsystem/extractor.go +++ b/pkg/subsystem/extractor.go @@ -56,10 +56,13 @@ func (e *Extractor) Extract(crashes []*Crash) []*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 { + // If we do not exclude parents, there'll always be a root subsystem in there + // and, as a result, subsystems reproducers will always replace all other ones. + withoutParents := removeParents(subsystems) newSubsystems := []*Subsystem{} for _, reproSubsystem := range fromRepro { parents := reproSubsystem.ReachableParents() - for _, subsystem := range subsystems { + for _, subsystem := range withoutParents { if _, ok := parents[subsystem]; ok { newSubsystems = append(newSubsystems, reproSubsystem) break @@ -71,21 +74,10 @@ func (e *Extractor) Extract(crashes []*Crash) []*Subsystem { } } - // If there are both parents and children, remove parents. - ignore := make(map[*Subsystem]struct{}) - for _, entry := range subsystems { - for p := range entry.ReachableParents() { - ignore[p] = struct{}{} - } - } - // And calculate counts. counts := make(map[*Subsystem]int) maxCount := 0 - for _, entry := range subsystems { - if _, ok := ignore[entry]; ok { - continue - } + for _, entry := range removeParents(append(subsystems, fromRepro...)) { counts[entry]++ if counts[entry] > maxCount { maxCount = counts[entry] @@ -102,3 +94,21 @@ func (e *Extractor) Extract(crashes []*Crash) []*Subsystem { } return ret } + +func removeParents(subsystems []*Subsystem) []*Subsystem { + // If there are both parents and children, remove parents. + ignore := make(map[*Subsystem]struct{}) + for _, entry := range subsystems { + for p := range entry.ReachableParents() { + ignore[p] = struct{}{} + } + } + var ret []*Subsystem + for _, entry := range subsystems { + if _, ok := ignore[entry]; ok { + continue + } + ret = append(ret, entry) + } + return ret +} diff --git a/pkg/subsystem/lists/linux_test.go b/pkg/subsystem/lists/linux_test.go index 8a3893f55..6107ff68f 100644 --- a/pkg/subsystem/lists/linux_test.go +++ b/pkg/subsystem/lists/linux_test.go @@ -76,8 +76,27 @@ symlinkat(&(0x7f00000004c0)='./file0aaaaaaaaaa/file0\x00', 0xffffffffffffff9c, & `), }, }, + // There should be no mm in the subsystems. expect: []string{"ntfs3"}, }, + { + name: "dri bug with usb call", + crashes: []*subsystem.Crash{ + { + GuiltyPath: `drivers/gpu/drm/udl/udl_drv.c`, + }, + { + GuiltyPath: `drivers/gpu/drm/udl/udl_drv.c`, + SyzRepro: []byte(` +# https://syzkaller.appspot.com/bug?id=56e9aec9bc3b5378c9b231a3f4b3329cf9f80990 +# See https://goo.gl/kgGztJ for information about syzkaller reproducers. +#{"procs":1,"slowdown":1,"sandbox":"none","sandbox_arg":0,"tun":true,"netdev":true,"close_fds":true} +syz_usb_connect(0x0, 0x24, &(0x7f0000000140)=ANY=[@ANYBLOB="12010000abbe6740e9174e8b089c000000010902120001000000000904000800ff"], 0x0) +`), + }, + }, + expect: []string{"dri"}, + }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { |
