aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/subsystem/extractor.go27
-rw-r--r--pkg/subsystem/extractor_test.go30
-rw-r--r--pkg/subsystem/lists/linux_test.go19
3 files changed, 69 insertions, 7 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 {
diff --git a/pkg/subsystem/extractor_test.go b/pkg/subsystem/extractor_test.go
index a78509e0f..ec725a556 100644
--- a/pkg/subsystem/extractor_test.go
+++ b/pkg/subsystem/extractor_test.go
@@ -12,11 +12,13 @@ import (
func TestExtractor(t *testing.T) {
// Objects used in tests.
- fsPath := "fs/"
+ fsPath, mmFsPath := "fs/", "mm/fs.c"
extProg, nfsProg, extNfsProg := []byte("ext"), []byte("nfs"), []byte("ext nfs")
- fs := &Subsystem{Name: "fs"}
+ all := &Subsystem{Name: "fs"}
+ fs := &Subsystem{Name: "fs", Parents: []*Subsystem{all}}
ext := &Subsystem{Name: "ext", Parents: []*Subsystem{fs}}
nfs := &Subsystem{Name: "nfs", Parents: []*Subsystem{fs}}
+ mm := &Subsystem{Name: "mm", Parents: []*Subsystem{all}}
// Tests themselves.
tests := []struct {
name string
@@ -79,11 +81,33 @@ func TestExtractor(t *testing.T) {
},
want: []*Subsystem{ext},
},
+ {
+ name: `Reproducer supporting one of guilty paths`,
+ crashes: []*Crash{
+ // The guilty paths correspond both to mm and fs.
+ {
+ GuiltyPath: mmFsPath,
+ },
+ {
+ GuiltyPath: mmFsPath,
+ },
+ {
+ GuiltyPath: mmFsPath,
+ },
+ {
+ // But one reproducer points clearly to fs.
+ GuiltyPath: mmFsPath,
+ SyzRepro: extProg,
+ },
+ },
+ want: []*Subsystem{ext},
+ },
}
extractor := &Extractor{
raw: &testRawExtractor{
perPath: map[string][]*Subsystem{
- fsPath: {fs},
+ fsPath: {fs},
+ mmFsPath: {mm, fs},
},
perProg: []progSubsystems{
{extProg, []*Subsystem{ext}},
diff --git a/pkg/subsystem/lists/linux_test.go b/pkg/subsystem/lists/linux_test.go
index 4f53948fd..8a3893f55 100644
--- a/pkg/subsystem/lists/linux_test.go
+++ b/pkg/subsystem/lists/linux_test.go
@@ -59,6 +59,25 @@ symlinkat(&(0x7f00000004c0)='./file0aaaaaaaaaa/file0\x00', 0xffffffffffffff9c, &
},
expect: []string{"ntfs3"},
},
+ {
+ name: `a bug with page cache in guilty path`,
+ crashes: []*subsystem.Crash{
+ {
+ GuiltyPath: `mm/filemap.c`,
+ },
+ {
+ GuiltyPath: `mm/filemap.c`,
+ SyzRepro: []byte(`# https://syzkaller.appspot.com/bug?id=cdaf5ed409125df023889aefe50b4cc4a41c0973
+# See https://goo.gl/kgGztJ for information about syzkaller reproducers.
+#{"threaded":true,"repeat":true,"procs":6,"slowdown":1,"sandbox":"","sandbox_arg":0,"close_fds":false,"ieee802154":true,"sysctl":true,"tmpdir":true,"segv":true}
+syz_mount_image$ntfs3(&(0x7f000001f740), &(0x7f000001f780)='./file0\x00', 0x0, &(0x7f0000000200)=ANY=[@ANYBLOB="64697363==")
+mkdirat(0xffffffffffffff9c, &(0x7f0000000600)='./file0aaaaaaaaaaaaaaaaa\x00', 0x0)
+symlinkat(&(0x7f00000004c0)='./file0aaaaaaaaaa/file0\x00', 0xffffffffffffff9c, &(0x7f0000000280)='./file0aaaaaa/file0\x00')
+`),
+ },
+ },
+ expect: []string{"ntfs3"},
+ },
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {