diff options
author | Dmitry Vyukov <dvyukov@google.com> | 2019-11-06 11:39:02 +0100 |
---|---|---|
committer | Dmitry Vyukov <dvyukov@google.com> | 2019-11-06 11:41:05 +0100 |
commit | da505f84d3e8fc3bb7c54fea76eb5574987ee01a (patch) | |
tree | 1744e28afcc5c1ee6ab874000bac35c53bc598dd | |
parent | 424cf6e8a12577719dc310bce2cce2a91723cf54 (diff) | |
download | syzkaller-da505f84d3e8fc3bb7c54fea76eb5574987ee01a.tar.gz |
pkg/report: detect syzkaller panics in lost connection bugs
Some syzkaller panics happen due to memory corruptions,
but it still would be useful at least to get some visibility into these crashes.
On some OSes we actualy already detect them as they have "panic:" oops pattern,
but not e.g. on linux.
Fixes #318
-rw-r--r-- | pkg/report/akaros.go | 4 | ||||
-rw-r--r-- | pkg/report/freebsd.go | 4 | ||||
-rw-r--r-- | pkg/report/fuchsia.go | 17 | ||||
-rw-r--r-- | pkg/report/gvisor.go | 26 | ||||
-rw-r--r-- | pkg/report/linux.go | 4 | ||||
-rw-r--r-- | pkg/report/netbsd.go | 4 | ||||
-rw-r--r-- | pkg/report/openbsd.go | 4 | ||||
-rw-r--r-- | pkg/report/report.go | 16 | ||||
-rw-r--r-- | pkg/report/report_test.go | 42 | ||||
-rw-r--r-- | pkg/report/testdata/all/report/0 | 19 | ||||
-rw-r--r-- | pkg/report/testdata/all/report/1 | 25 | ||||
-rw-r--r-- | pkg/report/testdata/all/report/2 | 22 | ||||
-rw-r--r-- | pkg/report/testdata/all/report/3 | 17 | ||||
-rw-r--r-- | pkg/report/testdata/all/report/4 | 22 |
14 files changed, 163 insertions, 63 deletions
diff --git a/pkg/report/akaros.go b/pkg/report/akaros.go index 83f3cf3f4..8a328fce9 100644 --- a/pkg/report/akaros.go +++ b/pkg/report/akaros.go @@ -133,7 +133,7 @@ var akarosStackParams = &stackParams{ }, } -var akarosOopses = []*oops{ +var akarosOopses = append([]*oops{ { []byte("kernel panic"), []oopsFormat{ @@ -188,4 +188,4 @@ var akarosOopses = []*oops{ }, []*regexp.Regexp{}, }, -} +}, commonOopses...) diff --git a/pkg/report/freebsd.go b/pkg/report/freebsd.go index c5ced44d8..38716df45 100644 --- a/pkg/report/freebsd.go +++ b/pkg/report/freebsd.go @@ -73,7 +73,7 @@ func (ctx *freebsd) Symbolize(rep *Report) error { var freebsdStackParams = &stackParams{} -var freebsdOopses = []*oops{ +var freebsdOopses = append([]*oops{ { []byte("Fatal trap"), []oopsFormat{ @@ -123,4 +123,4 @@ var freebsdOopses = []*oops{ }, []*regexp.Regexp{}, }, -} +}, commonOopses...) diff --git a/pkg/report/fuchsia.go b/pkg/report/fuchsia.go index 25facf658..df64055e4 100644 --- a/pkg/report/fuchsia.go +++ b/pkg/report/fuchsia.go @@ -185,7 +185,7 @@ var zirconStackParams = &stackParams{ }, } -var zirconOopses = []*oops{ +var zirconOopses = append([]*oops{ { []byte("ZIRCON KERNEL PANIC"), []oopsFormat{ @@ -316,17 +316,4 @@ var zirconOopses = []*oops{ compile("<== fatal exception: process .+?syz.+?\\["), }, }, - { - // Panics in Go services. - []byte("panic: "), - []oopsFormat{ - { - title: compile("panic: .*"), - report: compile("panic: (.*)(?:.*\\n)+?.* goroutine"), - fmt: "panic: %[1]v", - noStackTrace: true, - }, - }, - []*regexp.Regexp{}, - }, -} +}, commonOopses...) diff --git a/pkg/report/gvisor.go b/pkg/report/gvisor.go index 958e98975..ebe790e78 100644 --- a/pkg/report/gvisor.go +++ b/pkg/report/gvisor.go @@ -95,18 +95,7 @@ var gvisorTitleReplacement = []replacement{ }, } -var gvisorOopses = []*oops{ - { - []byte("panic:"), - []oopsFormat{ - { - title: compile("panic:(.*)"), - fmt: "panic:%[1]v", - noStackTrace: true, - }, - }, - []*regexp.Regexp{}, - }, +var gvisorOopses = append([]*oops{ { []byte("Panic:"), []oopsFormat{ @@ -130,17 +119,6 @@ var gvisorOopses = []*oops{ []*regexp.Regexp{}, }, { - []byte("runtime error:"), - []oopsFormat{ - { - title: compile("runtime error:(.*)"), - fmt: "runtime error:%[1]v", - noStackTrace: true, - }, - }, - []*regexp.Regexp{}, - }, - { []byte("SIGSEGV:"), []oopsFormat{ { @@ -197,4 +175,4 @@ var gvisorOopses = []*oops{ }, []*regexp.Regexp{}, }, -} +}, commonOopses...) diff --git a/pkg/report/linux.go b/pkg/report/linux.go index 5a7bb79d1..f57011fed 100644 --- a/pkg/report/linux.go +++ b/pkg/report/linux.go @@ -853,7 +853,7 @@ func warningStackFmt(skip ...string) *stackFmt { } } -var linuxOopses = []*oops{ +var linuxOopses = append([]*oops{ { []byte("BUG:"), []oopsFormat{ @@ -1584,4 +1584,4 @@ var linuxOopses = []*oops{ }, []*regexp.Regexp{}, }, -} +}, commonOopses...) diff --git a/pkg/report/netbsd.go b/pkg/report/netbsd.go index 45c7c2717..5ebdc7524 100644 --- a/pkg/report/netbsd.go +++ b/pkg/report/netbsd.go @@ -145,7 +145,7 @@ func (ctx *netbsd) symbolizeLine(symbFunc func(bin string, pc uint64) ([]symboli } // nolint: lll -var netbsdOopses = []*oops{ +var netbsdOopses = append([]*oops{ { []byte("fault in supervisor mode"), []oopsFormat{ @@ -188,4 +188,4 @@ var netbsdOopses = []*oops{ }, []*regexp.Regexp{}, }, -} +}, commonOopses...) diff --git a/pkg/report/openbsd.go b/pkg/report/openbsd.go index 7757afe3d..5d1821b14 100644 --- a/pkg/report/openbsd.go +++ b/pkg/report/openbsd.go @@ -136,7 +136,7 @@ func (ctx *openbsd) symbolizeLine(symbFunc func(bin string, pc uint64) ([]symbol return symbolized } -var openbsdOopses = []*oops{ +var openbsdOopses = append([]*oops{ { []byte("cleaned vnode"), []oopsFormat{ @@ -235,4 +235,4 @@ var openbsdOopses = []*oops{ compile("reorder_kernel"), }, }, -} +}, commonOopses...) diff --git a/pkg/report/report.go b/pkg/report/report.go index a434b3313..4528a0404 100644 --- a/pkg/report/report.go +++ b/pkg/report/report.go @@ -593,3 +593,19 @@ var ( filenameRe = regexp.MustCompile(`[a-zA-Z0-9_\-\./]*[a-zA-Z0-9_\-]+\.(c|h):[0-9]+`) reportFrameRe = regexp.MustCompile(`.* in ([a-zA-Z0-9_]+)`) ) + +// These are produced by syzkaller itself. +// But also catches crashes in Go programs in gvisor/fuchsia. +var commonOopses = []*oops{ + { + []byte("panic:"), + []oopsFormat{ + { + title: compile("panic:(.*)"), + fmt: "panic:%[1]v", + noStackTrace: true, + }, + }, + []*regexp.Regexp{}, + }, +} diff --git a/pkg/report/report_test.go b/pkg/report/report_test.go index 3c966e751..aebcb45f8 100644 --- a/pkg/report/report_test.go +++ b/pkg/report/report_test.go @@ -303,15 +303,9 @@ func testGuiltyFile(t *testing.T, reporter Reporter, fn string) { } func forEachFile(t *testing.T, dir string, fn func(t *testing.T, reporter Reporter, fn string)) { - testFilenameRe := regexp.MustCompile("^[0-9]+$") for os := range ctors { - path := filepath.Join("testdata", os, dir) - if !osutil.IsExist(path) { - continue - } - files, err := ioutil.ReadDir(path) - if err != nil { - t.Fatal(err) + if os == "windows" { + continue // not implemented } cfg := &mgrconfig.Config{ TargetOS: os, @@ -321,15 +315,35 @@ func forEachFile(t *testing.T, dir string, fn func(t *testing.T, reporter Report if err != nil { t.Fatal(err) } - for _, file := range files { - if !testFilenameRe.MatchString(file.Name()) { - continue - } - t.Run(fmt.Sprintf("%v/%v", os, file.Name()), func(t *testing.T) { - fn(t, reporter, filepath.Join(path, file.Name())) + for _, file := range readDir(t, filepath.Join("testdata", os, dir)) { + t.Run(fmt.Sprintf("%v/%v", os, filepath.Base(file)), func(t *testing.T) { + fn(t, reporter, file) }) } + for _, file := range readDir(t, filepath.Join("testdata", "all", dir)) { + t.Run(fmt.Sprintf("%v/all/%v", os, filepath.Base(file)), func(t *testing.T) { + fn(t, reporter, file) + }) + } + } +} + +func readDir(t *testing.T, dir string) (files []string) { + if !osutil.IsExist(dir) { + return nil + } + entries, err := ioutil.ReadDir(dir) + if err != nil { + t.Fatal(err) + } + testFilenameRe := regexp.MustCompile("^[0-9]+$") + for _, ent := range entries { + if !testFilenameRe.MatchString(ent.Name()) { + continue + } + files = append(files, filepath.Join(dir, ent.Name())) } + return } func TestReplace(t *testing.T) { diff --git a/pkg/report/testdata/all/report/0 b/pkg/report/testdata/all/report/0 new file mode 100644 index 000000000..4e27256e7 --- /dev/null +++ b/pkg/report/testdata/all/report/0 @@ -0,0 +1,19 @@ +TITLE: panic: bad arg kind + +panic: bad arg kind + +goroutine 25 [running]: +github.com/google/syzkaller/prog.clone(0x0, 0x0, 0xc003ab9e38, 0xc001037040, 0x10) + /syzkaller/gopath/src/github.com/google/syzkaller/prog/clone.go:75 +0x8b8 +github.com/google/syzkaller/prog.clone(0x97ca80, 0xc001d3f650, 0xc003ab9e38, 0xc00184bf70, 0x30) + /syzkaller/gopath/src/github.com/google/syzkaller/prog/clone.go:53 +0x17c +github.com/google/syzkaller/prog.clone(0x97ca80, 0xc001d3f680, 0xc003ab9e38, 0xc003ab9ec8, 0x30) + /syzkaller/gopath/src/github.com/google/syzkaller/prog/clone.go:53 +0x17c +github.com/google/syzkaller/prog.clone(0x97cac0, 0xc001d3f6b0, 0xc003ab9e38, 0x97cb00, 0xc0022c7940) + /syzkaller/gopath/src/github.com/google/syzkaller/prog/clone.go:40 +0x570 +github.com/google/syzkaller/prog.(*Prog).Clone(0xc001d8d100, 0xc002fdb470) + /syzkaller/gopath/src/github.com/google/syzkaller/prog/clone.go:20 +0x270 +main.(*Proc).loop(0xc002fc86c0) + /syzkaller/gopath/src/github.com/google/syzkaller/syz-fuzzer/proc.go:98 +0x3cb +created by main.main + /syzkaller/gopath/src/github.com/google/syzkaller/syz-fuzzer/fuzzer.go:258 +0x111b diff --git a/pkg/report/testdata/all/report/1 b/pkg/report/testdata/all/report/1 new file mode 100644 index 000000000..914c1bc6b --- /dev/null +++ b/pkg/report/testdata/all/report/1 @@ -0,0 +1,25 @@ +TITLE: panic: no result + +panic: no result + +goroutine 36 [running]: +github.com/google/syzkaller/prog.(*ResultArg).serialize(0xc005120640, 0xc005177420) + /home/ghani/go/src/github.com/google/syzkaller/prog/encoding.go:172 +0x3a7 +github.com/google/syzkaller/prog.(*serializer).arg(0xc005177420, 0x9f5ec0, 0xc005120640) + /home/ghani/go/src/github.com/google/syzkaller/prog/encoding.go:80 +0x40 +github.com/google/syzkaller/prog.(*serializer).call(0xc005177420, 0xc005120600) + /home/ghani/go/src/github.com/google/syzkaller/prog/encoding.go:70 +0x1d6 +github.com/google/syzkaller/prog.(*Prog).Serialize(0xc0051205c0, 0xc00516fb30, 0x717465, 0xc00516fb38) + /home/ghani/go/src/github.com/google/syzkaller/prog/encoding.go:35 +0xc8 +main.(*Proc).logProgram(0xc000101fc0, 0xc0000240e0, 0xc0051205c0) + /home/ghani/go/src/github.com/google/syzkaller/syz-fuzzer/proc.go:316 +0x59 +main.(*Proc).executeRaw(0xc000101fc0, 0xc0000240e0, 0xc0051205c0, 0x5, 0x0) + /home/ghani/go/src/github.com/google/syzkaller/syz-fuzzer/proc.go:293 +0xd4 +main.(*Proc).execute(0xc000101fc0, 0xc0000240e0, 0xc0051205c0, 0x0, 0x5, 0x1) + /home/ghani/go/src/github.com/google/syzkaller/syz-fuzzer/proc.go:259 +0x67 +main.(*Proc).smashInput(0xc000101fc0, 0xc004f79f50) + /home/ghani/go/src/github.com/google/syzkaller/syz-fuzzer/proc.go:223 +0x1d4 +main.(*Proc).loop(0xc000101fc0) + /home/ghani/go/src/github.com/google/syzkaller/syz-fuzzer/proc.go:84 +0x12f +created by main.main + /home/ghani/go/src/github.com/google/syzkaller/syz-fuzzer/fuzzer.go:242 +0x1011 diff --git a/pkg/report/testdata/all/report/2 b/pkg/report/testdata/all/report/2 new file mode 100644 index 000000000..c8aecab31 --- /dev/null +++ b/pkg/report/testdata/all/report/2 @@ -0,0 +1,22 @@ +TITLE: panic: executor 2: failed: event already set (errno 0) + +panic: executor 2: failed: event already set (errno 0) +child failed (errno 2) +loop failed (errno 0) + + +goroutine 16 [running]: +main.(*Proc).executeRaw(0x442002b480, 0x44200cafa0, 0x44280cbee0, 0x4, 0x0, 0x0, 0x0) + /home/jbtheou/go/src/github.com/google/syzkaller/syz-fuzzer/proc.go:271 +0x39c +main.(*Proc).execute(0x442002b480, 0x44200cafa0, 0x44280cbee0, 0x0, 0x4, 0x442625ce60, 0x1, 0x2a7260) + /home/jbtheou/go/src/github.com/google/syzkaller/syz-fuzzer/proc.go:231 +0x40 +main.(*Proc).triageInput.func1(0x44280cbee0, 0x4, 0x1) + /home/jbtheou/go/src/github.com/google/syzkaller/syz-fuzzer/proc.go:145 +0x88 +github.com/google/syzkaller/prog.Minimize(0x4423334b60, 0x6, 0x200, 0x4424751de8, 0x442b100e10, 0x7) + /home/jbtheou/go/src/github.com/google/syzkaller/prog/minimization.go:43 +0x10c +main.(*Proc).triageInput(0x442002b480, 0x4423531ec0) + /home/jbtheou/go/src/github.com/google/syzkaller/syz-fuzzer/proc.go:142 +0x658 +main.(*Proc).loop(0x442002b480) + /home/jbtheou/go/src/github.com/google/syzkaller/syz-fuzzer/proc.go:72 +0xe4 +created by main.main + /home/jbtheou/go/src/github.com/google/syzkaller/syz-fuzzer/fuzzer.go:294 +0xc90 diff --git a/pkg/report/testdata/all/report/3 b/pkg/report/testdata/all/report/3 new file mode 100644 index 000000000..4def1e43f --- /dev/null +++ b/pkg/report/testdata/all/report/3 @@ -0,0 +1,17 @@ +TITLE: panic: first open arg is not a pointer to string const + +panic: first open arg is not a pointer to string const + +goroutine 1 [running]: +github.com/google/syzkaller/pkg/host.extractStringConst(0x6858e0, 0xecfde0, 0x0, 0x0, 0xffffffffffffffff) + /home/thesis/gopath/src/github.com/google/syzkaller/pkg/host/host_linux.go:167 +0xdc +github.com/google/syzkaller/pkg/host.isSupportedOpenAt(0xb413e0, 0x7) + /home/thesis/gopath/src/github.com/google/syzkaller/pkg/host/host_linux.go:153 +0x3c +github.com/google/syzkaller/pkg/host.isSupported(0x4421a14000, 0x53eadf, 0x7ffe00, 0xb413e0, 0x4420081f00) + /home/thesis/gopath/src/github.com/google/syzkaller/pkg/host/host_linux.go:52 +0x178 +github.com/google/syzkaller/pkg/host.DetectSupportedSyscalls(0x44201d4480, 0x4420081f80, 0xb4df80, 0x442190701e) + /home/thesis/gopath/src/github.com/google/syzkaller/pkg/host/host_linux.go:34 +0xd0 +main.buildCallList(0x44201d4480, 0x44218ec000, 0x1904, 0xf) + /home/thesis/gopath/src/github.com/google/syzkaller/syz-fuzzer/fuzzer.go:459 +0xbc +main.main() + /home/thesis/gopath/src/github.com/google/syzkaller/syz-fuzzer/fuzzer.go:155 +0x44c diff --git a/pkg/report/testdata/all/report/4 b/pkg/report/testdata/all/report/4 new file mode 100644 index 000000000..4f2827c1c --- /dev/null +++ b/pkg/report/testdata/all/report/4 @@ -0,0 +1,22 @@ +TITLE: panic: runtime error: invalid memory address or nil pointer dereference + +panic: runtime error: invalid memory address or nil pointer dereference +[signal SIGSEGV: segmentation violation code=0x1 addr=0x88 pc=0x7a0381] + +goroutine 24 [running]: +github.com/google/syzkaller/prog.chooseCall.func1(0x9a6240, 0xc00306eb40, 0xc003ac0b60) + /syzkaller/gopath/src/github.com/google/syzkaller/prog/mutation.go:198 +0x51 +github.com/google/syzkaller/prog.foreachArgImpl(0x9a6240, 0xc00306eb40, 0xc003035fc8, 0x0, 0x0, 0x0, 0xc002effd60) + /syzkaller/gopath/src/github.com/google/syzkaller/prog/analysis.go:125 +0xbe +github.com/google/syzkaller/prog.ForeachArg(0xc003035fc0, 0xc002effd60) + /syzkaller/gopath/src/github.com/google/syzkaller/prog/analysis.go:120 +0x9e +github.com/google/syzkaller/prog.chooseCall(0xc002fc8080, 0xc003ac9420, 0xc002c616b0, 0xc002effdc0) + /syzkaller/gopath/src/github.com/google/syzkaller/prog/mutation.go:197 +0x10d +github.com/google/syzkaller/prog.(*mutator).mutateArg(0xc002effec0, 0xa) + /syzkaller/gopath/src/github.com/google/syzkaller/prog/mutation.go:161 +0x67 +github.com/google/syzkaller/prog.(*Prog).Mutate(0xc002fc8080, 0x9a0ac0, 0xc002c0d560, 0x1e, 0xc002e96980, 0xc003022000, 0x1e78, 0x2400) + /syzkaller/gopath/src/github.com/google/syzkaller/prog/mutation.go:44 +0x2da +main.(*Proc).loop(0xc002fe2500) + /syzkaller/gopath/src/github.com/google/syzkaller/syz-fuzzer/proc.go:99 +0x434 +created by main.main + /syzkaller/gopath/src/github.com/google/syzkaller/syz-fuzzer/fuzzer.go:259 +0x114c |