From c8a08b381ddaa35d4e58e91b7d7d215c9fc66b87 Mon Sep 17 00:00:00 2001 From: Aleksandr Nogikh Date: Thu, 15 Jun 2023 14:31:29 +0200 Subject: pkg/report: move report.Type to pkg/report/crash This will help avoid a circular dependency pkg/vcs -> pkg/report -> pkg/vcs. --- pkg/instance/instance.go | 3 +- pkg/report/akaros.go | 5 +- pkg/report/crash/types.go | 21 ++++++++ pkg/report/darwin.go | 6 ++- pkg/report/freebsd.go | 6 ++- pkg/report/fuchsia.go | 13 ++--- pkg/report/gvisor.go | 14 +++--- pkg/report/linux.go | 119 +++++++++++++++++++++++----------------------- pkg/report/netbsd.go | 8 ++-- pkg/report/openbsd.go | 14 +++--- pkg/report/report.go | 45 +++++------------- pkg/report/report_test.go | 11 +++-- pkg/repro/repro.go | 16 ++++--- syz-manager/hub.go | 5 +- syz-manager/manager.go | 15 +++--- 15 files changed, 161 insertions(+), 140 deletions(-) create mode 100644 pkg/report/crash/types.go diff --git a/pkg/instance/instance.go b/pkg/instance/instance.go index 73cef6931..3dd654f2b 100644 --- a/pkg/instance/instance.go +++ b/pkg/instance/instance.go @@ -21,6 +21,7 @@ import ( "github.com/google/syzkaller/pkg/mgrconfig" "github.com/google/syzkaller/pkg/osutil" "github.com/google/syzkaller/pkg/report" + "github.com/google/syzkaller/pkg/report/crash" "github.com/google/syzkaller/pkg/tool" "github.com/google/syzkaller/pkg/vcs" "github.com/google/syzkaller/sys/targets" @@ -308,7 +309,7 @@ func (inst *inst) test() EnvTestResult { testErr.Title, testErr.Output = bootErr.BootError() ret.RawOutput = testErr.Output rep := inst.reporter.Parse(testErr.Output) - if rep != nil && rep.Type == report.UnexpectedReboot { + if rep != nil && rep.Type == crash.UnexpectedReboot { // Avoid detecting any boot crash as "unexpected kernel reboot". rep = inst.reporter.ParseFrom(testErr.Output, rep.SkipPos) } diff --git a/pkg/report/akaros.go b/pkg/report/akaros.go index a18ef9361..b097cc664 100644 --- a/pkg/report/akaros.go +++ b/pkg/report/akaros.go @@ -12,6 +12,7 @@ import ( "strconv" "strings" + "github.com/google/syzkaller/pkg/report/crash" "github.com/google/syzkaller/pkg/symbolizer" ) @@ -165,7 +166,7 @@ var akarosOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { []byte("kernel warning"), @@ -188,6 +189,6 @@ var akarosOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, }, commonOopses...) diff --git a/pkg/report/crash/types.go b/pkg/report/crash/types.go new file mode 100644 index 000000000..e83853024 --- /dev/null +++ b/pkg/report/crash/types.go @@ -0,0 +1,21 @@ +// Copyright 2023 syzkaller project authors. All rights reserved. +// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. + +package crash + +type Type string + +const ( + UnknownType = Type("") + Hang = Type("HANG") + MemoryLeak = Type("LEAK") + DataRace = Type("DATARACE") + UnexpectedReboot = Type("REBOOT") + UBSAN = Type("UBSAN") + Bug = Type("BUG") + Warning = Type("WARNING") + KASAN = Type("KASAN") + LockdepBug = Type("LOCKDEP") + AtomicSleep = Type("ATOMIC_SLEEP") + KMSAN = Type("KMSAN") +) diff --git a/pkg/report/darwin.go b/pkg/report/darwin.go index 8bbc12c0c..8b257b9bf 100644 --- a/pkg/report/darwin.go +++ b/pkg/report/darwin.go @@ -5,6 +5,8 @@ package report import ( "regexp" + + "github.com/google/syzkaller/pkg/report/crash" ) func ctorDarwin(cfg *config) (reporterImpl, []string, error) { @@ -43,7 +45,7 @@ var darwinOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { []byte("Debugger: Unexpected kernel trap number:"), @@ -54,6 +56,6 @@ var darwinOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, }, commonOopses...) diff --git a/pkg/report/freebsd.go b/pkg/report/freebsd.go index daab68a74..8342d026b 100644 --- a/pkg/report/freebsd.go +++ b/pkg/report/freebsd.go @@ -6,6 +6,8 @@ package report import ( "bytes" "regexp" + + "github.com/google/syzkaller/pkg/report/crash" ) type freebsd struct { @@ -92,7 +94,7 @@ var freebsdOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { []byte("panic:"), @@ -140,6 +142,6 @@ var freebsdOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, }, commonOopses...) diff --git a/pkg/report/fuchsia.go b/pkg/report/fuchsia.go index ca8d2f571..157ae9a4a 100644 --- a/pkg/report/fuchsia.go +++ b/pkg/report/fuchsia.go @@ -12,6 +12,7 @@ import ( "strconv" "strings" + "github.com/google/syzkaller/pkg/report/crash" "github.com/google/syzkaller/pkg/symbolizer" "github.com/ianlancetaylor/demangle" ) @@ -253,7 +254,7 @@ var zirconOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { []byte("recursion in interrupt handler"), @@ -274,7 +275,7 @@ var zirconOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, // We should detect just "stopping other cpus" as some kernel crash rather then as "lost connection", // but if we add oops for "stopping other cpus", then it will interfere with other formats, @@ -289,11 +290,11 @@ var zirconOopses = append([]*oops{ title: compile("welcome to Zircon"), fmt: "unexpected kernel reboot", noStackTrace: true, - reportType: UnexpectedReboot, + reportType: crash.UnexpectedReboot, }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { []byte("KVM internal error"), @@ -305,7 +306,7 @@ var zirconOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { []byte("<== fatal exception"), @@ -320,6 +321,6 @@ var zirconOopses = append([]*oops{ []*regexp.Regexp{ compile("<== fatal exception: process .+?syz.+?\\["), }, - UnknownType, + crash.UnknownType, }, }, commonOopses...) diff --git a/pkg/report/gvisor.go b/pkg/report/gvisor.go index cf34be473..268065e59 100644 --- a/pkg/report/gvisor.go +++ b/pkg/report/gvisor.go @@ -6,6 +6,8 @@ package report import ( "bytes" "regexp" + + "github.com/google/syzkaller/pkg/report/crash" ) type gvisor struct { @@ -104,7 +106,7 @@ var gvisorOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { []byte("SIGSEGV:"), @@ -116,7 +118,7 @@ var gvisorOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { []byte("SIGBUS:"), @@ -128,7 +130,7 @@ var gvisorOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { []byte("FATAL ERROR:"), @@ -140,7 +142,7 @@ var gvisorOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { []byte("WARNING: DATA RACE"), @@ -153,7 +155,7 @@ var gvisorOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { []byte("Invalid request partialResult"), @@ -166,6 +168,6 @@ var gvisorOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, }, commonOopses...) diff --git a/pkg/report/linux.go b/pkg/report/linux.go index a13a326bd..7e7ea0d89 100644 --- a/pkg/report/linux.go +++ b/pkg/report/linux.go @@ -15,6 +15,7 @@ import ( "time" "github.com/google/syzkaller/pkg/osutil" + "github.com/google/syzkaller/pkg/report/crash" "github.com/google/syzkaller/pkg/symbolizer" "github.com/google/syzkaller/pkg/vcs" "github.com/google/syzkaller/sys/targets" @@ -639,7 +640,7 @@ func (ctx *linux) parseOpcodes(codeSlice string) (parsedOpcodes, error) { // decompileOpcodes detects the most meaningful "Code: " lines from the report, decompiles // them and appends a human-readable listing to the end of the report. func (ctx *linux) decompileOpcodes(text []byte, report *Report) []byte { - if report.Type == Hang { + if report.Type == crash.Hang { // Even though Hang reports do contain the Code: section, there's no point in // decompiling that. So just return the text. return text @@ -1324,7 +1325,7 @@ var linuxOopses = append([]*oops{ // These frames are present in KASAN_HW_TAGS reports. skip: []string{"kernel_fault", "tag_check", "mem_abort", "^el1_", "^el1h_"}, }, - reportType: KASAN, + reportType: crash.KASAN, }, { title: compile("BUG: KASAN:"), @@ -1339,18 +1340,18 @@ var linuxOopses = append([]*oops{ }, skip: []string{"slab_", "kfree", "vunmap", "vfree"}, }, - reportType: KASAN, + reportType: crash.KASAN, }, { title: compile("BUG: KASAN: ([a-z\\-]+) on address(?:.*\\n)+?.*(Read|Write) of size ([0-9]+)"), fmt: "KASAN: %[1]v %[2]v", - reportType: KASAN, + reportType: crash.KASAN, }, { title: compile("BUG: KASAN: (.*)"), fmt: "KASAN: %[1]v", corrupted: true, - reportType: KASAN, + reportType: crash.KASAN, }, { title: compile("BUG: KMSAN: kernel-usb-infoleak"), @@ -1390,7 +1391,7 @@ var linuxOopses = append([]*oops{ report: compile("BUG: KCSAN: (.*)"), fmt: "KCSAN: %[1]v", noStackTrace: true, - reportType: DataRace, + reportType: crash.DataRace, }, { title: compile("BUG: KCSAN:"), @@ -1485,7 +1486,7 @@ var linuxOopses = append([]*oops{ }, skip: []string{"spin_", "_lock", "_unlock"}, }, - reportType: LockdepBug, + reportType: crash.LockdepBug, }, { title: compile("BUG: soft lockup"), @@ -1499,13 +1500,13 @@ var linuxOopses = append([]*oops{ }, extractor: linuxStallFrameExtractor, }, - reportType: Hang, + reportType: crash.Hang, }, { title: compile("BUG: .*still has locks held!"), report: compile("BUG: .*still has locks held!(?:.*\\n)+?.*{{PC}} +{{FUNC}}"), fmt: "BUG: still has locks held in %[1]v", - reportType: LockdepBug, + reportType: crash.LockdepBug, }, { title: compile("BUG: scheduling while atomic"), @@ -1517,7 +1518,7 @@ var linuxOopses = append([]*oops{ }, skip: []string{"schedule"}, }, - reportType: AtomicSleep, + reportType: crash.AtomicSleep, }, { title: compile("BUG: lock held when returning to user space"), @@ -1535,13 +1536,13 @@ var linuxOopses = append([]*oops{ parseStackTrace, }, }, - reportType: LockdepBug, + reportType: crash.LockdepBug, }, { title: compile("BUG: held lock freed!"), report: compile("BUG: held lock freed!(?:.*\\n)+?.*{{PC}} +{{FUNC}}"), fmt: "BUG: held lock freed in %[1]v", - reportType: LockdepBug, + reportType: crash.LockdepBug, }, { title: compile("BUG: Bad rss-counter state"), @@ -1589,7 +1590,7 @@ var linuxOopses = append([]*oops{ parseStackTrace, }, }, - reportType: AtomicSleep, + reportType: crash.AtomicSleep, }, { title: compile("BUG: using ([a-z_]+)\\(\\) in preemptible"), @@ -1622,7 +1623,7 @@ var linuxOopses = append([]*oops{ "idr_get", "list_lru_init", "kasprintf", "kvasprintf", "pcpu_create", "strdup", "strndup", "memdup"}, }, - reportType: MemoryLeak, + reportType: crash.MemoryLeak, }, { title: compile("BUG: .*stack guard page was hit at"), @@ -1650,7 +1651,7 @@ var linuxOopses = append([]*oops{ }, skip: []string{"lock_sock", "release_sock"}, }, - reportType: LockdepBug, + reportType: crash.LockdepBug, }, { title: compile(`BUG:[[:space:]]*(?:\n|$)`), @@ -1669,7 +1670,7 @@ var linuxOopses = append([]*oops{ // pkg/host output in debug mode. compile("BUG: no syscalls can create resource"), }, - UnknownType, + crash.UnknownType, }, { []byte("WARNING:"), @@ -1706,26 +1707,26 @@ var linuxOopses = append([]*oops{ title: compile("WARNING: .*kernel/locking/lockdep\\.c.*lock_"), fmt: "WARNING: locking bug in %[1]v", stack: warningStackFmt("lock_sock", "release_sock"), - reportType: LockdepBug, + reportType: crash.LockdepBug, }, { title: compile("WARNING: .*still has locks held!"), report: compile("WARNING: .*still has locks held!(?:.*\\n)+?.*at: {{FUNC}}"), fmt: "WARNING: still has locks held in %[1]v", - reportType: LockdepBug, + reportType: crash.LockdepBug, }, { title: compile("WARNING: Nested lock was not taken"), fmt: "WARNING: nested lock was not taken in %[1]v", stack: warningStackFmt(), - reportType: LockdepBug, + reportType: crash.LockdepBug, }, { title: compile("WARNING: lock held when returning to user space"), report: compile("WARNING: lock held when returning to user space(?:.*\\n)+?.*leaving the kernel with locks still held(?:.*\\n)+?.*at: (?:{{PC}} +)?{{FUNC}}"), fmt: "WARNING: lock held when returning to user space in %[1]v", noStackTrace: true, - reportType: LockdepBug, + reportType: crash.LockdepBug, }, { title: compile("WARNING: .*mm/.*\\.c.* k?.?malloc"), @@ -1763,13 +1764,13 @@ var linuxOopses = append([]*oops{ skip: []string{"process_one_work", "flush_workqueue", "drain_workqueue", "destroy_workqueue"}, }, - reportType: LockdepBug, + reportType: crash.LockdepBug, }, { title: compile("WARNING: possible irq lock inversion dependency detected"), report: compile("WARNING: possible irq lock inversion dependency detected(?:.*\\n)+?.*just changed the state of lock(?:.*\\n)+?.*at: (?:{{PC}} +)?{{FUNC}}"), fmt: "possible deadlock in %[1]v", - reportType: LockdepBug, + reportType: crash.LockdepBug, }, { title: compile("WARNING: .*-safe -> .*-unsafe lock order detected"), @@ -1780,13 +1781,13 @@ var linuxOopses = append([]*oops{ parseStackTrace, }, }, - reportType: LockdepBug, + reportType: crash.LockdepBug, }, { title: compile("WARNING: possible recursive locking detected"), report: compile("WARNING: possible recursive locking detected(?:.*\\n)+?.*is trying to acquire lock(?:.*\\n)+?.*at: (?:{{PC}} +)?{{FUNC}}"), fmt: "possible deadlock in %[1]v", - reportType: LockdepBug, + reportType: crash.LockdepBug, }, { title: compile("WARNING: inconsistent lock state"), @@ -1798,7 +1799,7 @@ var linuxOopses = append([]*oops{ parseStackTrace, }, }, - reportType: LockdepBug, + reportType: crash.LockdepBug, }, { title: compile("WARNING: suspicious RCU usage"), @@ -1811,7 +1812,7 @@ var linuxOopses = append([]*oops{ }, skip: []string{"rcu", "kmem", "slab"}, }, - reportType: LockdepBug, + reportType: crash.LockdepBug, }, { title: compile("WARNING: kernel stack regs at [0-9a-f]+ in [^ ]* has bad '([^']+)' value"), @@ -1835,13 +1836,13 @@ var linuxOopses = append([]*oops{ parseStackTrace, }, }, - reportType: LockdepBug, + reportType: crash.LockdepBug, }, { title: compile("WARNING: held lock freed!"), report: compile("WARNING: held lock freed!(?:.*\\n)+?.*at:(?: {{PC}})? +{{FUNC}}"), fmt: "WARNING: held lock freed in %[1]v", - reportType: LockdepBug, + reportType: crash.LockdepBug, }, { title: compile("WARNING: kernel stack regs .* has bad 'bp' value"), @@ -1870,7 +1871,7 @@ var linuxOopses = append([]*oops{ compile("WARNING: Unprivileged eBPF is enabled with eIBRS"), compile(`WARNING: fbcon: Driver '(.*)' missed to adjust virtual screen size (\((?:\d+)x(?:\d+) vs\. (?:\d+)x(?:\d+)\))`), }, - Warning, + crash.Warning, }, { []byte("INFO:"), @@ -1879,31 +1880,31 @@ var linuxOopses = append([]*oops{ title: compile("INFO: possible circular locking dependency detected"), report: compile("INFO: possible circular locking dependency detected \\](?:.*\\n)+?.*is trying to acquire lock(?:.*\\n)+?.*at: {{PC}} +{{FUNC}}"), fmt: "possible deadlock in %[1]v", - reportType: LockdepBug, + reportType: crash.LockdepBug, }, { title: compile("INFO: possible irq lock inversion dependency detected"), report: compile("INFO: possible irq lock inversion dependency detected \\](?:.*\\n)+?.*just changed the state of lock(?:.*\\n)+?.*at: {{PC}} +{{FUNC}}"), fmt: "possible deadlock in %[1]v", - reportType: LockdepBug, + reportType: crash.LockdepBug, }, { title: compile("INFO: SOFTIRQ-safe -> SOFTIRQ-unsafe lock order detected"), report: compile("INFO: SOFTIRQ-safe -> SOFTIRQ-unsafe lock order detected \\](?:.*\\n)+?.*is trying to acquire(?:.*\\n)+?.*at: {{PC}} +{{FUNC}}"), fmt: "possible deadlock in %[1]v", - reportType: LockdepBug, + reportType: crash.LockdepBug, }, { title: compile("INFO: possible recursive locking detected"), report: compile("INFO: possible recursive locking detected \\](?:.*\\n)+?.*is trying to acquire lock(?:.*\\n)+?.*at: {{PC}} +{{FUNC}}"), fmt: "possible deadlock in %[1]v", - reportType: LockdepBug, + reportType: crash.LockdepBug, }, { title: compile("INFO: inconsistent lock state"), report: compile("INFO: inconsistent lock state \\](?:.*\\n)+?.*takes(?:.*\\n)+?.*at: {{PC}} +{{FUNC}}"), fmt: "inconsistent lock state in %[1]v", - reportType: LockdepBug, + reportType: crash.LockdepBug, }, { title: compile("INFO: rcu_(?:preempt|sched|bh) (?:self-)?detected(?: expedited)? stall"), @@ -1922,7 +1923,7 @@ var linuxOopses = append([]*oops{ skip: []string{"apic_timer_interrupt", "rcu"}, extractor: linuxStallFrameExtractor, }, - reportType: Hang, + reportType: crash.Hang, }, { title: compile("INFO: trying to register non-static key"), @@ -1958,7 +1959,7 @@ var linuxOopses = append([]*oops{ }, extractor: linuxHangTaskFrameExtractor, }, - reportType: Hang, + reportType: crash.Hang, }, { title: compile("INFO: task .* can't die for more than .* seconds"), @@ -1971,7 +1972,7 @@ var linuxOopses = append([]*oops{ }, skip: []string{"schedule"}, }, - reportType: Hang, + reportType: crash.Hang, }, { // This gets captured for corrupted old-style KASAN reports. @@ -1997,7 +1998,7 @@ var linuxOopses = append([]*oops{ compile("CAM_INFO:"), // Android prints this. compile("rmt_storage:INFO:"), // Android prints this. }, - UnknownType, + crash.UnknownType, }, { []byte("Unable to handle kernel"), @@ -2016,7 +2017,7 @@ var linuxOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { []byte("general protection fault"), @@ -2037,7 +2038,7 @@ var linuxOopses = append([]*oops{ []*regexp.Regexp{ compile(`general protection fault .* error:\d+ in `), }, - UnknownType, + crash.UnknownType, }, { []byte("stack segment: "), @@ -2055,7 +2056,7 @@ var linuxOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { []byte("Kernel panic"), @@ -2141,7 +2142,7 @@ var linuxOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { []byte("PANIC: double fault"), @@ -2157,7 +2158,7 @@ var linuxOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { []byte("kernel BUG"), @@ -2199,7 +2200,7 @@ var linuxOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - Bug, + crash.Bug, }, { []byte("Kernel BUG"), @@ -2210,7 +2211,7 @@ var linuxOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - Bug, + crash.Bug, }, { []byte("BUG kmalloc-"), @@ -2221,7 +2222,7 @@ var linuxOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { []byte("divide error:"), @@ -2237,7 +2238,7 @@ var linuxOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { // A misspelling of the above introduced in 9d06c4027f21 ("x86/entry: Convert Divide Error to IDTENTRY"). @@ -2254,7 +2255,7 @@ var linuxOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { []byte("invalid opcode:"), @@ -2270,7 +2271,7 @@ var linuxOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { []byte("UBSAN:"), @@ -2313,7 +2314,7 @@ var linuxOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UBSAN, + crash.UBSAN, }, { []byte("Booting the kernel."), @@ -2322,7 +2323,7 @@ var linuxOopses = append([]*oops{ title: compile("Booting the kernel."), fmt: "unexpected kernel reboot", noStackTrace: true, - reportType: UnexpectedReboot, + reportType: crash.UnexpectedReboot, }, }, []*regexp.Regexp{ @@ -2331,7 +2332,7 @@ var linuxOopses = append([]*oops{ // as an invalid mount option and we detect false reboot. compile("Parsing ELF|Decompressing Linux"), }, - UnknownType, + crash.UnknownType, }, { []byte("unregister_netdevice: waiting for"), @@ -2343,7 +2344,7 @@ var linuxOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { // Custom vfs error printed by older versions of the kernel, see #3621. @@ -2356,7 +2357,7 @@ var linuxOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { // Custom vfs error printed by older versions of the kernel, see #3621. @@ -2369,7 +2370,7 @@ var linuxOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { []byte("Internal error:"), @@ -2391,7 +2392,7 @@ var linuxOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { []byte("Unhandled fault:"), @@ -2412,7 +2413,7 @@ var linuxOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { []byte("Alignment trap:"), @@ -2430,7 +2431,7 @@ var linuxOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { []byte("trusty: panic"), @@ -2454,6 +2455,6 @@ var linuxOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, }, commonOopses...) diff --git a/pkg/report/netbsd.go b/pkg/report/netbsd.go index 19854c1f7..6097bbf4b 100644 --- a/pkg/report/netbsd.go +++ b/pkg/report/netbsd.go @@ -5,6 +5,8 @@ package report import ( "regexp" + + "github.com/google/syzkaller/pkg/report/crash" ) func ctorNetbsd(cfg *config) (reporterImpl, []string, error) { @@ -31,7 +33,7 @@ var netbsdOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { []byte("panic: "), @@ -65,7 +67,7 @@ var netbsdOopses = append([]*oops{ []*regexp.Regexp{ compile(`ddb\.onpanic:`), }, - UnknownType, + crash.UnknownType, }, { []byte("UBSan:"), @@ -76,6 +78,6 @@ var netbsdOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, }, commonOopses...) diff --git a/pkg/report/openbsd.go b/pkg/report/openbsd.go index 55efabe9a..67a2fc092 100644 --- a/pkg/report/openbsd.go +++ b/pkg/report/openbsd.go @@ -5,6 +5,8 @@ package report import ( "regexp" + + "github.com/google/syzkaller/pkg/report/crash" ) func ctorOpenbsd(cfg *config) (reporterImpl, []string, error) { @@ -36,7 +38,7 @@ var openbsdOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { []byte("panic:"), @@ -91,7 +93,7 @@ var openbsdOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { []byte("lock order reversal:"), @@ -106,7 +108,7 @@ var openbsdOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { []byte("witness:"), @@ -125,7 +127,7 @@ var openbsdOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { []byte("uvm_fault("), @@ -147,7 +149,7 @@ var openbsdOopses = append([]*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { []byte("kernel:"), @@ -164,6 +166,6 @@ var openbsdOopses = append([]*oops{ []*regexp.Regexp{ compile("reorder_kernel"), }, - UnknownType, + crash.UnknownType, }, }, commonOopses...) diff --git a/pkg/report/report.go b/pkg/report/report.go index 4af55382b..4498945c6 100644 --- a/pkg/report/report.go +++ b/pkg/report/report.go @@ -13,6 +13,7 @@ import ( "strings" "github.com/google/syzkaller/pkg/mgrconfig" + "github.com/google/syzkaller/pkg/report/crash" "github.com/google/syzkaller/pkg/vcs" "github.com/google/syzkaller/sys/targets" ) @@ -43,7 +44,7 @@ type Report struct { // If two crashes have a non-empty intersection of Title/AltTitles, they are considered the same bug. AltTitles []string // Bug type (e.g. hang, memory leak, etc). - Type Type + Type crash.Type // The indicative function name. Frame string // Report contains whole oops text. @@ -75,28 +76,8 @@ func (r Report) String() string { return fmt.Sprintf("crash: %v\n%s", r.Title, r.Report) } -type Type string - -const ( - UnknownType = Type("") - Hang = Type("HANG") - MemoryLeak = Type("LEAK") - DataRace = Type("DATARACE") - UnexpectedReboot = Type("REBOOT") - UBSAN = Type("UBSAN") - Bug = Type("BUG") - Warning = Type("WARNING") - KASAN = Type("KASAN") - LockdepBug = Type("LOCKDEP") - AtomicSleep = Type("ATOMIC_SLEEP") - KMSAN = Type("KMSAN") - // unspecifiedType can be used to cancel oops.reportType from oopsFormat.reportType. - unspecifiedType = Type("UNSPECIFIED") -) - -func (t Type) String() string { - return string(t) -} +// unspecifiedType can be used to cancel oops.reportType from oopsFormat.reportType. +const unspecifiedType = crash.Type("UNSPECIFIED") // NewReporter creates reporter for the specified OS/Type. func NewReporter(cfg *mgrconfig.Config) (*Reporter, error) { @@ -246,10 +227,10 @@ func (reporter *Reporter) Symbolize(rep *Report) error { func setReportType(rep *Report, oops *oops, format oopsFormat) { if format.reportType == unspecifiedType { - rep.Type = UnknownType - } else if format.reportType != UnknownType { + rep.Type = crash.UnknownType + } else if format.reportType != crash.UnknownType { rep.Type = format.reportType - } else if oops.reportType != UnknownType { + } else if oops.reportType != crash.UnknownType { rep.Type = oops.reportType } } @@ -411,7 +392,7 @@ type oops struct { formats []oopsFormat suppressions []*regexp.Regexp // This reportType will be used if oopsFormat's reportType is empty. - reportType Type + reportType crash.Type } type oopsFormat struct { @@ -433,7 +414,7 @@ type oopsFormat struct { noStackTrace bool corrupted bool // If not empty, report will have this type. - reportType Type + reportType crash.Type } type stackFmt struct { @@ -782,7 +763,7 @@ var commonOopses = []*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { // Errors produced by log.Fatal functions. @@ -796,7 +777,7 @@ var commonOopses = []*oops{ }, }, []*regexp.Regexp{}, - UnknownType, + crash.UnknownType, }, { []byte("panic:"), @@ -821,7 +802,7 @@ var commonOopses = []*oops{ compile(`ddb\.onpanic:`), compile(`evtlog_status:`), }, - UnknownType, + crash.UnknownType, }, { []byte("fatal error:"), @@ -835,6 +816,6 @@ var commonOopses = []*oops{ []*regexp.Regexp{ compile("ALSA"), }, - UnknownType, + crash.UnknownType, }, } diff --git a/pkg/report/report_test.go b/pkg/report/report_test.go index f6fa08cd8..ba41735a5 100644 --- a/pkg/report/report_test.go +++ b/pkg/report/report_test.go @@ -18,6 +18,7 @@ import ( "github.com/google/syzkaller/pkg/mgrconfig" "github.com/google/syzkaller/pkg/osutil" + "github.com/google/syzkaller/pkg/report/crash" "github.com/google/syzkaller/pkg/testutil" "github.com/google/syzkaller/sys/targets" ) @@ -33,7 +34,7 @@ type ParseTest struct { Log []byte Title string AltTitles []string - Type Type + Type crash.Type Frame string StartLine string EndLine string @@ -111,7 +112,7 @@ func parseHeaderLine(t *testing.T, test *ParseTest, ln string) { case strings.HasPrefix(ln, altTitlePrefix): test.AltTitles = append(test.AltTitles, ln[len(altTitlePrefix):]) case strings.HasPrefix(ln, typePrefix): - test.Type = Type(ln[len(typePrefix):]) + test.Type = crash.Type(ln[len(typePrefix):]) case strings.HasPrefix(ln, framePrefix): test.Frame = ln[len(framePrefix):] case strings.HasPrefix(ln, startPrefix): @@ -157,7 +158,7 @@ func testParseImpl(t *testing.T, reporter *Reporter, test *ParseTest) { if rep != nil && rep.Type == unspecifiedType { t.Fatalf("unspecifiedType leaked outside") } - title, corrupted, corruptedReason, suppressed, typ, frame := "", false, "", false, UnknownType, "" + title, corrupted, corruptedReason, suppressed, typ, frame := "", false, "", false, crash.UnknownType, "" var altTitles []string if rep != nil { title = rep.Title @@ -239,13 +240,13 @@ func checkReport(t *testing.T, reporter *Reporter, rep *Report, test *ParseTest) } func updateReportTest(t *testing.T, test *ParseTest, title string, altTitles []string, corrupted, suppressed bool, - typ Type, frame string) { + typ crash.Type, frame string) { buf := new(bytes.Buffer) fmt.Fprintf(buf, "TITLE: %v\n", title) for _, t := range altTitles { fmt.Fprintf(buf, "ALT: %v\n", t) } - if typ != UnknownType { + if typ != crash.UnknownType { fmt.Fprintf(buf, "TYPE: %v\n", typ) } if test.Frame != "" { diff --git a/pkg/repro/repro.go b/pkg/repro/repro.go index f86e75af2..e2548def4 100644 --- a/pkg/repro/repro.go +++ b/pkg/repro/repro.go @@ -17,6 +17,7 @@ import ( "github.com/google/syzkaller/pkg/log" "github.com/google/syzkaller/pkg/mgrconfig" "github.com/google/syzkaller/pkg/report" + "github.com/google/syzkaller/pkg/report/crash" "github.com/google/syzkaller/prog" "github.com/google/syzkaller/sys/targets" "github.com/google/syzkaller/vm" @@ -50,7 +51,7 @@ type context struct { target *targets.Target reporter *report.Reporter crashTitle string - crashType report.Type + crashType crash.Type crashStart int entries []*prog.LogEntry instances chan *reproInstance @@ -98,7 +99,7 @@ func prepareCtx(crashLog []byte, cfg *mgrconfig.Config, features *host.Features, return nil, ErrNoPrograms } crashStart := len(crashLog) - crashTitle, crashType := "", report.UnknownType + crashTitle, crashType := "", crash.UnknownType if rep := reporter.Parse(crashLog); rep != nil { crashStart = rep.StartPos crashTitle = rep.Title @@ -117,10 +118,10 @@ func prepareCtx(crashLog []byte, cfg *mgrconfig.Config, features *host.Features, // No output can only be reproduced with the max timeout. // As a compromise we use the smallest and the largest timeouts. testTimeouts = []time.Duration{testTimeouts[0], testTimeouts[2]} - case crashType == report.MemoryLeak: + case crashType == crash.MemoryLeak: // Memory leaks can't be detected quickly because of expensive setup and scanning. testTimeouts = testTimeouts[1:] - case crashType == report.Hang: + case crashType == crash.Hang: testTimeouts = testTimeouts[2:] } ctx := &context{ @@ -171,9 +172,10 @@ func (ctx *context) run() (*Result, *Stats, error) { return res, ctx.stats, nil } -func createStartOptions(cfg *mgrconfig.Config, features *host.Features, crashType report.Type) csource.Options { +func createStartOptions(cfg *mgrconfig.Config, features *host.Features, + crashType crash.Type) csource.Options { opts := csource.DefaultOpts(cfg) - if crashType == report.MemoryLeak { + if crashType == crash.MemoryLeak { opts.Leak = true } if features != nil { @@ -538,7 +540,7 @@ func (ctx *context) testWithInstance(callback func(execInterface) (rep *instance ctx.reproLogf(2, "suppressed program crash: %v", rep.Title) return false, nil } - if ctx.crashType == report.MemoryLeak && rep.Type != report.MemoryLeak { + if ctx.crashType == crash.MemoryLeak && rep.Type != crash.MemoryLeak { ctx.reproLogf(2, "not a leak crash: %v", rep.Title) return false, nil } diff --git a/syz-manager/hub.go b/syz-manager/hub.go index 8b4334503..3b04719bc 100644 --- a/syz-manager/hub.go +++ b/syz-manager/hub.go @@ -14,6 +14,7 @@ import ( "github.com/google/syzkaller/pkg/log" "github.com/google/syzkaller/pkg/mgrconfig" "github.com/google/syzkaller/pkg/report" + "github.com/google/syzkaller/pkg/report/crash" "github.com/google/syzkaller/pkg/rpctype" "github.com/google/syzkaller/prog" ) @@ -277,9 +278,9 @@ func (hc *HubConnector) processRepros(repros [][]byte) int { // On a leak instance we override repro type to leak, // because otherwise repro package won't even enable leak detection // and we won't reproduce leaks from other instances. - typ := report.UnknownType + typ := crash.UnknownType if hc.leak { - typ = report.MemoryLeak + typ = crash.MemoryLeak } hc.hubReproQueue <- &Crash{ vmIndex: -1, diff --git a/syz-manager/manager.go b/syz-manager/manager.go index c0d6f028d..914941172 100644 --- a/syz-manager/manager.go +++ b/syz-manager/manager.go @@ -31,6 +31,7 @@ import ( "github.com/google/syzkaller/pkg/mgrconfig" "github.com/google/syzkaller/pkg/osutil" "github.com/google/syzkaller/pkg/report" + crash_pkg "github.com/google/syzkaller/pkg/report/crash" "github.com/google/syzkaller/pkg/repro" "github.com/google/syzkaller/pkg/rpctype" "github.com/google/syzkaller/pkg/signal" @@ -862,12 +863,12 @@ func (mgr *Manager) saveCrash(crash *Crash) bool { if err := mgr.reporter.Symbolize(crash.Report); err != nil { log.Errorf("failed to symbolize report: %v", err) } - if crash.Type == report.MemoryLeak { + if crash.Type == crash_pkg.MemoryLeak { mgr.mu.Lock() mgr.memoryLeakFrames[crash.Frame] = true mgr.mu.Unlock() } - if crash.Type == report.DataRace { + if crash.Type == crash_pkg.DataRace { mgr.mu.Lock() mgr.dataRaceFrames[crash.Frame] = true mgr.mu.Unlock() @@ -897,7 +898,7 @@ func (mgr *Manager) saveCrash(crash *Crash) bool { mgr.mu.Unlock() if mgr.dash != nil { - if crash.Type == report.MemoryLeak { + if crash.Type == crash_pkg.MemoryLeak { return true } dc := &dashapi.Crash{ @@ -988,7 +989,7 @@ func (mgr *Manager) needRepro(crash *Crash) bool { return true } if mgr.checkResult == nil || (mgr.checkResult.Features[host.FeatureLeak].Enabled && - crash.Type != report.MemoryLeak) { + crash.Type != crash_pkg.MemoryLeak) { // Leak checking is very slow, don't bother reproducing other crashes on leak instance. return false } @@ -1000,7 +1001,7 @@ func (mgr *Manager) needRepro(crash *Crash) bool { Title: crash.Title, Corrupted: crash.Corrupted, Suppressed: crash.Suppressed, - MayBeMissing: crash.Type == report.MemoryLeak, // we did not send the original crash w/o repro + MayBeMissing: crash.Type == crash_pkg.MemoryLeak, // we did not send the original crash w/o repro } needRepro, err := mgr.dash.NeedRepro(cid) if err != nil { @@ -1011,7 +1012,7 @@ func (mgr *Manager) needRepro(crash *Crash) bool { func (mgr *Manager) saveFailedRepro(rep *report.Report, stats *repro.Stats) { if mgr.dash != nil { - if rep.Type == report.MemoryLeak { + if rep.Type == crash_pkg.MemoryLeak { // Don't send failed leak repro attempts to dashboard // as we did not send the crash itself. return @@ -1021,7 +1022,7 @@ func (mgr *Manager) saveFailedRepro(rep *report.Report, stats *repro.Stats) { Title: rep.Title, Corrupted: rep.Corrupted, Suppressed: rep.Suppressed, - MayBeMissing: rep.Type == report.MemoryLeak, + MayBeMissing: rep.Type == crash_pkg.MemoryLeak, } if err := mgr.dash.ReportFailedRepro(cid); err != nil { log.Logf(0, "failed to report failed repro to dashboard: %v", err) -- cgit mrf-deployment