aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/report
diff options
context:
space:
mode:
authorTaras Madan <tarasmadan@google.com>2025-06-20 20:10:18 +0200
committerTaras Madan <tarasmadan@google.com>2025-06-27 21:14:17 +0000
commitfb06623039ccebb3ffcddf239a7567a35658ca67 (patch)
tree94127db458836fd5d379d84bb168157649fc5396 /pkg/report
parent803ce19b0a8969a6e25644dad041eb2cffcda94f (diff)
pkg/report: factor out type definitions
Diffstat (limited to 'pkg/report')
-rw-r--r--pkg/report/darwin.go4
-rw-r--r--pkg/report/freebsd.go4
-rw-r--r--pkg/report/fuchsia.go8
-rw-r--r--pkg/report/gvisor.go9
-rw-r--r--pkg/report/linux.go163
-rw-r--r--pkg/report/netbsd.go5
-rw-r--r--pkg/report/openbsd.go8
-rw-r--r--pkg/report/report.go37
-rw-r--r--pkg/report/report_test.go5
-rw-r--r--pkg/report/title_to_type.go155
-rw-r--r--pkg/report/title_to_type_test.go39
11 files changed, 256 insertions, 181 deletions
diff --git a/pkg/report/darwin.go b/pkg/report/darwin.go
index 24ec74ab0..52a97ffea 100644
--- a/pkg/report/darwin.go
+++ b/pkg/report/darwin.go
@@ -5,8 +5,6 @@ package report
import (
"regexp"
-
- "github.com/google/syzkaller/pkg/report/crash"
)
func ctorDarwin(cfg *config) (reporterImpl, []string, error) {
@@ -45,7 +43,6 @@ var darwinOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
[]byte("Debugger: Unexpected kernel trap number:"),
@@ -56,7 +53,6 @@ var darwinOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
&groupGoRuntimeErrors,
}, commonOopses...)
diff --git a/pkg/report/freebsd.go b/pkg/report/freebsd.go
index 2b27b3034..37c50eaf8 100644
--- a/pkg/report/freebsd.go
+++ b/pkg/report/freebsd.go
@@ -5,8 +5,6 @@ package report
import (
"regexp"
-
- "github.com/google/syzkaller/pkg/report/crash"
)
type freebsd struct {
@@ -57,7 +55,6 @@ var freebsdOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
[]byte("panic:"),
@@ -105,7 +102,6 @@ var freebsdOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
&groupGoRuntimeErrors,
}, commonOopses...)
diff --git a/pkg/report/fuchsia.go b/pkg/report/fuchsia.go
index 4165e00c0..f165fbc76 100644
--- a/pkg/report/fuchsia.go
+++ b/pkg/report/fuchsia.go
@@ -11,7 +11,6 @@ import (
"strconv"
"strings"
- "github.com/google/syzkaller/pkg/report/crash"
"github.com/google/syzkaller/pkg/symbolizer"
"github.com/ianlancetaylor/demangle"
)
@@ -324,7 +323,6 @@ var zirconOopses = []*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
[]byte("recursion in interrupt handler"),
@@ -345,7 +343,6 @@ var zirconOopses = []*oops{
},
},
[]*regexp.Regexp{},
- 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,
@@ -360,11 +357,9 @@ var zirconOopses = []*oops{
title: compile("welcome to Zircon"),
fmt: "unexpected kernel reboot",
noStackTrace: true,
- reportType: crash.UnexpectedReboot,
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
[]byte("KVM internal error"),
@@ -376,7 +371,6 @@ var zirconOopses = []*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
[]byte("<== fatal exception"),
@@ -391,7 +385,6 @@ var zirconOopses = []*oops{
[]*regexp.Regexp{
compile("<== fatal exception: process .+?syz.+?\\["),
},
- crash.UnknownType,
},
}
@@ -412,7 +405,6 @@ var starnixOopses = []*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
}
diff --git a/pkg/report/gvisor.go b/pkg/report/gvisor.go
index 00c8e927c..b721af940 100644
--- a/pkg/report/gvisor.go
+++ b/pkg/report/gvisor.go
@@ -6,8 +6,6 @@ package report
import (
"bytes"
"regexp"
-
- "github.com/google/syzkaller/pkg/report/crash"
)
type gvisor struct {
@@ -106,7 +104,6 @@ var gvisorOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
[]byte("SIGSEGV:"),
@@ -118,7 +115,6 @@ var gvisorOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
[]byte("SIGBUS:"),
@@ -130,7 +126,6 @@ var gvisorOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
[]byte("FATAL ERROR:"),
@@ -142,7 +137,6 @@ var gvisorOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
[]byte("WARNING: DATA RACE"),
@@ -155,7 +149,6 @@ var gvisorOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
[]byte("Invalid request partialResult"),
@@ -168,7 +161,6 @@ var gvisorOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
[]byte("fatal error:"),
@@ -180,6 +172,5 @@ var gvisorOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
}, commonOopses...)
diff --git a/pkg/report/linux.go b/pkg/report/linux.go
index 3d03671bd..f714e55cd 100644
--- a/pkg/report/linux.go
+++ b/pkg/report/linux.go
@@ -188,7 +188,7 @@ func (ctx *linux) Parse(output []byte) *Report {
}
rep.reportPrefixLen = len(rep.Report)
rep.Report = append(rep.Report, report...)
- rep.setType(format.reportType, oops.defaultReportType)
+ rep.Type = titleToCrashType(rep.Title)
setExecutorInfo(rep)
if !rep.Corrupted {
rep.Corrupted, rep.CorruptedReason = isCorrupted(title, report, format)
@@ -1457,7 +1457,6 @@ var linuxOopses = append([]*oops{
// These frames are present in KASAN_HW_TAGS reports.
skip: []string{"kernel_fault", "tag_check", "mem_abort", "^el1_", "^el1h_"},
},
- reportType: crash.KASAN,
},
{
title: compile("BUG: KASAN:"),
@@ -1472,18 +1471,15 @@ var linuxOopses = append([]*oops{
},
skip: []string{"slab_", "kfree", "vunmap", "vfree"},
},
- 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: crash.KASAN,
+ title: compile("BUG: KASAN: ([a-z\\-]+) on address(?:.*\\n)+?.*(Read|Write) of size ([0-9]+)"),
+ fmt: "KASAN: %[1]v %[2]v",
},
{
- title: compile("BUG: KASAN: (.*)"),
- fmt: "KASAN: %[1]v",
- corrupted: true,
- reportType: crash.KASAN,
+ title: compile("BUG: KASAN: (.*)"),
+ fmt: "KASAN: %[1]v",
+ corrupted: true,
},
{
title: compile("BUG: KMSAN: kernel-usb-infoleak"),
@@ -1499,7 +1495,6 @@ var linuxOopses = append([]*oops{
skip: []string{"alloc_skb", "usb_submit_urb", "usb_start_wait_urb", "usb_bulk_msg", "usb_interrupt_msg", "usb_control_msg"},
},
noStackTrace: true,
- reportType: crash.KMSAN,
},
{
title: compile("BUG: KMSAN:"),
@@ -1517,14 +1512,12 @@ var linuxOopses = append([]*oops{
skip: []string{"alloc_skb", "netlink_ack", "netlink_rcv_skb"},
},
noStackTrace: true,
- reportType: crash.KMSAN,
},
{
title: compile("BUG: KCSAN: data-race"),
report: compile("BUG: KCSAN: (.*)"),
fmt: "KCSAN: %[1]v",
noStackTrace: true,
- reportType: crash.DataRace,
},
{
title: compile("BUG: KCSAN:"),
@@ -1619,7 +1612,6 @@ var linuxOopses = append([]*oops{
},
skip: []string{"spin_", "_lock", "_unlock"},
},
- reportType: crash.LockdepBug,
},
{
title: compile("BUG: soft lockup"),
@@ -1633,13 +1625,11 @@ var linuxOopses = append([]*oops{
},
extractor: linuxStallFrameExtractor,
},
- 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: crash.LockdepBug,
+ 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",
},
{
title: compile("BUG: scheduling while atomic"),
@@ -1651,7 +1641,6 @@ var linuxOopses = append([]*oops{
},
skip: []string{"schedule"},
},
- reportType: crash.AtomicSleep,
},
{
title: compile("BUG: lock held when returning to user space"),
@@ -1669,13 +1658,11 @@ var linuxOopses = append([]*oops{
parseStackTrace,
},
},
- 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: 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",
},
{
title: compile("BUG: Bad rss-counter state"),
@@ -1736,7 +1723,6 @@ var linuxOopses = append([]*oops{
parseStackTrace,
},
},
- reportType: crash.AtomicSleep,
},
{
title: compile("BUG: using ([a-z_]+)\\(\\) in preemptible"),
@@ -1769,7 +1755,6 @@ var linuxOopses = append([]*oops{
"idr_get", "list_lru_init", "kasprintf", "kvasprintf",
"pcpu_create", "strdup", "strndup", "memdup"},
},
- reportType: crash.MemoryLeak,
},
{
title: compile("BUG: .*stack guard page was hit at"),
@@ -1783,7 +1768,6 @@ var linuxOopses = append([]*oops{
},
extractor: linuxStallFrameExtractor,
},
- reportType: unspecifiedType, // This is a printk(), not a BUG_ON().
},
{
title: compile("BUG: Invalid wait context"),
@@ -1797,7 +1781,6 @@ var linuxOopses = append([]*oops{
},
skip: []string{"lock_sock", "release_sock"},
},
- reportType: crash.LockdepBug,
},
{
title: compile(`BUG:[[:space:]]*(?:\n|$)`),
@@ -1816,7 +1799,6 @@ var linuxOopses = append([]*oops{
// pkg/host output in debug mode.
compile("BUG: no syscalls can create resource"),
},
- crash.UnknownType,
},
{
[]byte("WARNING:"),
@@ -1850,29 +1832,25 @@ var linuxOopses = append([]*oops{
stack: warningStackFmt("refcount", "kobject_"),
},
{
- title: compile("WARNING: .*kernel/locking/lockdep\\.c.*lock_"),
- fmt: "WARNING: locking bug in %[1]v",
- stack: warningStackFmt("lock_sock", "release_sock"),
- reportType: crash.LockdepBug,
+ title: compile("WARNING: .*kernel/locking/lockdep\\.c.*lock_"),
+ fmt: "WARNING: locking bug in %[1]v",
+ stack: warningStackFmt("lock_sock", "release_sock"),
},
{
- 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: 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",
},
{
- title: compile("WARNING: Nested lock was not taken"),
- fmt: "WARNING: nested lock was not taken in %[1]v",
- stack: warningStackFmt(),
- reportType: crash.LockdepBug,
+ title: compile("WARNING: Nested lock was not taken"),
+ fmt: "WARNING: nested lock was not taken in %[1]v",
+ stack: warningStackFmt(),
},
{
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: crash.LockdepBug,
},
{
title: compile("WARNING: .*mm/.*\\.c.* k?.?malloc"),
@@ -1915,13 +1893,11 @@ var linuxOopses = append([]*oops{
skip: []string{"process_one_work", "flush_workqueue",
"drain_workqueue", "destroy_workqueue"},
},
- 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: 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",
},
{
title: compile("WARNING: .*-safe -> .*-unsafe lock order detected"),
@@ -1932,13 +1908,11 @@ var linuxOopses = append([]*oops{
parseStackTrace,
},
},
- 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: 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",
},
{
title: compile("WARNING: inconsistent lock state"),
@@ -1950,7 +1924,6 @@ var linuxOopses = append([]*oops{
parseStackTrace,
},
},
- reportType: crash.LockdepBug,
},
{
title: compile("WARNING: suspicious RCU usage"),
@@ -1963,19 +1936,16 @@ var linuxOopses = append([]*oops{
},
skip: []string{"rcu", "kmem", "slab"},
},
- reportType: crash.LockdepBug,
},
{
title: compile("WARNING: kernel stack regs at [0-9a-f]+ in [^ ]* has bad '([^']+)' value"),
fmt: "WARNING: kernel stack regs has bad '%[1]v' value",
noStackTrace: true,
- reportType: unspecifiedType, // This is printk().
},
{
title: compile("WARNING: kernel stack frame pointer at [0-9a-f]+ in [^ ]* has bad value"),
fmt: "WARNING: kernel stack frame pointer has bad value",
noStackTrace: true,
- reportType: unspecifiedType, // This is printk().
},
{
title: compile("WARNING: bad unlock balance detected!"),
@@ -1987,31 +1957,26 @@ var linuxOopses = append([]*oops{
parseStackTrace,
},
},
- 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: 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",
},
{
title: compile("WARNING: kernel stack regs .* has bad 'bp' value"),
fmt: "WARNING: kernel stack regs has bad value",
noStackTrace: true,
- reportType: unspecifiedType, // This is printk().
},
{
title: compile("WARNING: kernel stack frame pointer .* has bad value"),
fmt: "WARNING: kernel stack regs has bad value",
noStackTrace: true,
- reportType: unspecifiedType, // This is printk().
},
{
- title: compile(`WARNING:[[:space:]]*(?:\n|$)`),
- fmt: "WARNING: corrupted",
- corrupted: true,
- reportType: unspecifiedType, // This is printk().
+ title: compile(`WARNING:[[:space:]]*(?:\n|$)`),
+ fmt: "WARNING: corrupted",
+ corrupted: true,
},
},
[]*regexp.Regexp{
@@ -2027,40 +1992,34 @@ var linuxOopses = append([]*oops{
compile(`(?i)warning: .* uses (deprecated v2 capabilities|wireless extensions)`),
compile(`XFS \(\w+\): WARNING`),
},
- crash.Warning,
},
{
[]byte("INFO:"),
[]oopsFormat{
{
- 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: crash.LockdepBug,
+ 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",
},
{
- 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: 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",
},
{
- 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: 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",
},
{
- 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: 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",
},
{
- 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: 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",
},
{
title: compile("INFO: rcu_(?:preempt|sched|bh) (?:self-)?detected(?: expedited)? stall"),
@@ -2079,7 +2038,6 @@ var linuxOopses = append([]*oops{
skip: []string{"apic_timer_interrupt", "rcu"},
extractor: linuxStallFrameExtractor,
},
- reportType: crash.Hang,
},
{
title: compile("INFO: trying to register non-static key"),
@@ -2115,7 +2073,6 @@ var linuxOopses = append([]*oops{
},
extractor: linuxHangTaskFrameExtractor,
},
- reportType: crash.Hang,
},
{
title: compile("INFO: task .* can't die for more than .* seconds"),
@@ -2128,7 +2085,6 @@ var linuxOopses = append([]*oops{
},
skip: []string{"schedule"},
},
- reportType: crash.Hang,
},
{
// This gets captured for corrupted old-style KASAN reports.
@@ -2153,7 +2109,6 @@ var linuxOopses = append([]*oops{
compile("rmt_storage:INFO:"), // Android prints this.
compile("_INFO:"), // To filter out "INVALID BTF_INFO:NUM".
},
- crash.UnknownType,
},
{
[]byte("Unable to handle kernel"),
@@ -2172,7 +2127,6 @@ var linuxOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
[]byte("general protection fault"),
@@ -2193,7 +2147,6 @@ var linuxOopses = append([]*oops{
[]*regexp.Regexp{
compile(`general protection fault .* error:\d+ in `),
},
- crash.UnknownType,
},
{
[]byte("stack segment: "),
@@ -2211,7 +2164,6 @@ var linuxOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
[]byte("Kernel panic"),
@@ -2297,7 +2249,6 @@ var linuxOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
[]byte("PANIC: double fault"),
@@ -2313,7 +2264,6 @@ var linuxOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
[]byte("rust_kernel: panicked"),
@@ -2334,7 +2284,6 @@ var linuxOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
[]byte("kernel BUG"),
@@ -2376,7 +2325,6 @@ var linuxOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.Bug,
},
{
[]byte("Kernel BUG"),
@@ -2387,7 +2335,6 @@ var linuxOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.Bug,
},
{
[]byte("BUG kmalloc-"),
@@ -2398,7 +2345,6 @@ var linuxOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
[]byte("divide error:"),
@@ -2414,7 +2360,6 @@ var linuxOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
// A misspelling of the above introduced in 9d06c4027f21 ("x86/entry: Convert Divide Error to IDTENTRY").
@@ -2431,7 +2376,6 @@ var linuxOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
[]byte("invalid opcode:"),
@@ -2447,7 +2391,6 @@ var linuxOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
[]byte("UBSAN:"),
@@ -2490,7 +2433,6 @@ var linuxOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UBSAN,
},
{
[]byte("Booting the kernel."),
@@ -2499,7 +2441,6 @@ var linuxOopses = append([]*oops{
title: compile("^Booting the kernel"),
fmt: "unexpected kernel reboot",
noStackTrace: true,
- reportType: crash.UnexpectedReboot,
},
},
[]*regexp.Regexp{
@@ -2508,7 +2449,6 @@ var linuxOopses = append([]*oops{
// as an invalid mount option and we detect false reboot.
compile("Parsing ELF|Decompressing Linux|Unknown parameter '"),
},
- crash.UnknownType,
},
{
[]byte("unregister_netdevice: waiting for"),
@@ -2520,7 +2460,6 @@ var linuxOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
// Custom vfs error printed by older versions of the kernel, see #3621.
@@ -2533,7 +2472,6 @@ var linuxOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
// Custom vfs error printed by older versions of the kernel, see #3621.
@@ -2546,7 +2484,6 @@ var linuxOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
[]byte("Internal error:"),
@@ -2568,7 +2505,6 @@ var linuxOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
[]byte("Unhandled fault:"),
@@ -2589,7 +2525,6 @@ var linuxOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
[]byte("Alignment trap:"),
@@ -2607,7 +2542,6 @@ var linuxOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
[]byte("trusty: panic"),
@@ -2631,7 +2565,6 @@ var linuxOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
&groupGoRuntimeErrors,
}, commonOopses...)
diff --git a/pkg/report/netbsd.go b/pkg/report/netbsd.go
index 87509ac91..054dfa972 100644
--- a/pkg/report/netbsd.go
+++ b/pkg/report/netbsd.go
@@ -5,8 +5,6 @@ package report
import (
"regexp"
-
- "github.com/google/syzkaller/pkg/report/crash"
)
func ctorNetbsd(cfg *config) (reporterImpl, []string, error) {
@@ -33,7 +31,6 @@ var netbsdOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
[]byte("panic: "),
@@ -67,7 +64,6 @@ var netbsdOopses = append([]*oops{
[]*regexp.Regexp{
compile(`ddb\.onpanic:`),
},
- crash.UnknownType,
},
{
[]byte("UBSan:"),
@@ -78,7 +74,6 @@ var netbsdOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
&groupGoRuntimeErrors,
}, commonOopses...)
diff --git a/pkg/report/openbsd.go b/pkg/report/openbsd.go
index f4ea30e3f..2c7b1c1d3 100644
--- a/pkg/report/openbsd.go
+++ b/pkg/report/openbsd.go
@@ -5,8 +5,6 @@ package report
import (
"regexp"
-
- "github.com/google/syzkaller/pkg/report/crash"
)
func ctorOpenbsd(cfg *config) (reporterImpl, []string, error) {
@@ -38,7 +36,6 @@ var openbsdOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
[]byte("panic:"),
@@ -93,7 +90,6 @@ var openbsdOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
[]byte("lock order reversal:"),
@@ -108,7 +104,6 @@ var openbsdOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
[]byte("witness:"),
@@ -127,7 +122,6 @@ var openbsdOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
[]byte("uvm_fault("),
@@ -149,7 +143,6 @@ var openbsdOopses = append([]*oops{
},
},
[]*regexp.Regexp{},
- crash.UnknownType,
},
{
[]byte("kernel:"),
@@ -166,7 +159,6 @@ var openbsdOopses = append([]*oops{
[]*regexp.Regexp{
compile("reorder_kernel"),
},
- crash.UnknownType,
},
&groupGoRuntimeErrors,
}, commonOopses...)
diff --git a/pkg/report/report.go b/pkg/report/report.go
index a069fe058..3381607ea 100644
--- a/pkg/report/report.go
+++ b/pkg/report/report.go
@@ -83,19 +83,6 @@ type ExecutorInfo struct {
ExecID int // The program the syz-executor was executing.
}
-// unspecifiedType can be used to cancel oops.defaultReportType from oopsFormat.reportType.
-const unspecifiedType = crash.Type("UNSPECIFIED")
-
-func (rep *Report) setType(typ, defaultType crash.Type) {
- if typ == unspecifiedType {
- rep.Type = crash.UnknownType
- } else if typ != crash.UnknownType {
- rep.Type = typ
- } else {
- rep.Type = defaultType
- }
-}
-
func (rep *Report) String() string {
return fmt.Sprintf("crash: %v\n%s", rep.Title, rep.Report)
}
@@ -406,8 +393,6 @@ type oops struct {
header []byte
formats []oopsFormat
suppressions []*regexp.Regexp
- // defaultReportType will be used if oopsFormat's reportType is empty.
- defaultReportType crash.Type
}
type oopsFormat struct {
@@ -428,8 +413,6 @@ type oopsFormat struct {
// present, but this format does not comply with that.
noStackTrace bool
corrupted bool
- // If not empty, report will have this type.
- reportType crash.Type
}
type stackFmt struct {
@@ -811,14 +794,13 @@ func simpleLineParser(output []byte, oopses []*oops, params *stackParams, ignore
if oops == nil {
return nil
}
- title, corrupted, altTitles, format := extractDescription(output[rep.StartPos:], oops, params)
+ title, corrupted, altTitles, _ := extractDescription(output[rep.StartPos:], oops, params)
rep.Title = title
rep.AltTitles = altTitles
rep.Report = output[rep.StartPos:]
rep.Corrupted = corrupted != ""
rep.CorruptedReason = corrupted
- rep.setType(format.reportType, oops.defaultReportType)
-
+ rep.Type = titleToCrashType(rep.Title)
return rep
}
@@ -896,7 +878,6 @@ var commonOopses = []*oops{
},
},
[]*regexp.Regexp{},
- crash.SyzFailure,
},
{
// Errors produced by log.Fatal functions.
@@ -910,7 +891,6 @@ var commonOopses = []*oops{
},
},
[]*regexp.Regexp{},
- crash.SyzFailure,
},
{
[]byte("panic:"),
@@ -935,7 +915,6 @@ var commonOopses = []*oops{
compile(`ddb\.onpanic:`),
compile(`evtlog_status:`),
},
- crash.UnknownType,
},
}
@@ -952,5 +931,15 @@ var groupGoRuntimeErrors = oops{
compile("ALSA"),
compile("fatal error: cannot create timer"),
},
- crash.UnknownType,
+}
+
+func titleToCrashType(title string) crash.Type {
+ for _, t := range titleToType {
+ for _, prefix := range t.includePrefixes {
+ if strings.HasPrefix(title, prefix) {
+ return t.crashType
+ }
+ }
+ }
+ return crash.UnknownType
}
diff --git a/pkg/report/report_test.go b/pkg/report/report_test.go
index a14e87f95..739068787 100644
--- a/pkg/report/report_test.go
+++ b/pkg/report/report_test.go
@@ -208,7 +208,7 @@ func testFromReport(rep *Report) *ParseTest {
Corrupted: rep.Corrupted,
corruptedReason: rep.CorruptedReason,
Suppressed: rep.Suppressed,
- Type: rep.Type,
+ Type: titleToCrashType(rep.Title),
Frame: rep.Frame,
Report: rep.Report,
}
@@ -232,9 +232,6 @@ func testParseImpl(t *testing.T, reporter *Reporter, test *ParseTest) {
if rep != nil && rep.Title == "" {
t.Fatalf("found crash, but title is empty")
}
- if rep != nil && rep.Type == unspecifiedType {
- t.Fatalf("unspecifiedType leaked outside")
- }
parsed := testFromReport(rep)
if !test.Equal(parsed) {
if *flagUpdate && test.StartLine+test.EndLine == "" {
diff --git a/pkg/report/title_to_type.go b/pkg/report/title_to_type.go
new file mode 100644
index 000000000..f96b1cf4b
--- /dev/null
+++ b/pkg/report/title_to_type.go
@@ -0,0 +1,155 @@
+// Copyright 2025 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 report
+
+import (
+ "github.com/google/syzkaller/pkg/report/crash"
+)
+
+var titleToType = []struct {
+ includePrefixes []string
+ crashType crash.Type
+}{
+ {
+ includePrefixes: []string{"KCSAN: data-race"},
+ crashType: crash.DataRace,
+ },
+ {
+ includePrefixes: []string{"KFENCE: "},
+ crashType: crash.UnknownType,
+ },
+ {
+ includePrefixes: []string{
+ // keep-sorted start
+ "BUG: bad unlock balance in",
+ "BUG: held lock freed in",
+ "BUG: rwlock",
+ "BUG: spinlock",
+ "BUG: still has locks held in",
+ "WARNING: bad unlock balance in",
+ "WARNING: held lock freed in",
+ "WARNING: lock held",
+ "WARNING: locking bug in",
+ "WARNING: nested lock was not taken in",
+ "WARNING: still has locks held in",
+ "WARNING: suspicious RCU usage in",
+ "inconsistent lock state in",
+ "possible deadlock in",
+ // keep-sorted end
+ },
+ crashType: crash.LockdepBug,
+ },
+ {
+ includePrefixes: []string{
+ // keep-sorted start
+ "BUG: scheduling while atomic in",
+ "BUG: sleeping function called from invalid context in",
+ // keep-sorted end
+ },
+ crashType: crash.AtomicSleep,
+ },
+ {
+ includePrefixes: []string{"memory leak in"},
+ crashType: crash.MemoryLeak,
+ },
+ {
+ includePrefixes: []string{
+ // keep-sorted start
+ "BUG: bad usercopy in",
+ "BUG: corrupted list in",
+ "kernel BUG ",
+ // keep-sorted end
+ },
+ crashType: crash.Bug,
+ },
+ {
+ includePrefixes: []string{"WARNING in"},
+ crashType: crash.Warning,
+ },
+ {
+ includePrefixes: []string{
+ // keep-sorted start
+ "BUG: stack guard page was hit in",
+ "WARNING: corrupted",
+ "WARNING: kernel stack frame pointer has bad value",
+ "WARNING: kernel stack regs has bad",
+ // keep-sorter end
+ },
+ crashType: crash.UnknownType, // This is printk().
+ },
+ {
+ includePrefixes: []string{
+ // keep-sorted start
+ "BUG: soft lockup in",
+ "INFO: rcu detected stall in",
+ "INFO: task can't die in",
+ "INFO: task hung in",
+ // keep-sorted end
+ },
+ crashType: crash.Hang,
+ },
+ {
+ includePrefixes: []string{
+ // keep-sorted start
+ "Alignment trap in",
+ "BUG: Object already free",
+ "BUG: unable to handle kernel",
+ "Internal error in",
+ "PANIC: double fault",
+ "Unhandled fault in",
+ "VFS: Busy inodes after unmount (use-after-free)",
+ "VFS: Close: file count is zero (use-after-free)",
+ "divide error in",
+ "general protection fault in",
+ "go runtime error",
+ "invalid opcode in",
+ "kernel panic: ",
+ "kernel stack overflow",
+ "panic:",
+ "rust_kernel panicked",
+ "stack segment fault in",
+ "trusty:",
+ "unregister_netdevice: waiting for DEV to become free",
+ // keep-sorted end
+ },
+ crashType: crash.UnknownType,
+ },
+ {
+ includePrefixes: []string{"unexpected kernel reboot"},
+ crashType: crash.UnexpectedReboot,
+ },
+ {
+ includePrefixes: []string{
+ "SYZFAIL",
+ "SYZFATAL:",
+ },
+ crashType: crash.SyzFailure,
+ },
+
+ // DEFAULTS.
+ {
+ includePrefixes: []string{"WARNING: "},
+ crashType: crash.Warning,
+ },
+ {
+ includePrefixes: []string{"BUG: "},
+ crashType: crash.UnknownType,
+ },
+ {
+ includePrefixes: []string{"INFO: "},
+ crashType: crash.UnknownType,
+ },
+ {
+ includePrefixes: []string{"KASAN: "},
+ crashType: crash.KASAN,
+ },
+ {
+ includePrefixes: []string{"KMSAN: "},
+ crashType: crash.KMSAN,
+ },
+ {
+ includePrefixes: []string{"UBSAN: "},
+ crashType: crash.UBSAN,
+ },
+}
diff --git a/pkg/report/title_to_type_test.go b/pkg/report/title_to_type_test.go
new file mode 100644
index 000000000..a152a3445
--- /dev/null
+++ b/pkg/report/title_to_type_test.go
@@ -0,0 +1,39 @@
+// Copyright 2025 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 report
+
+import (
+ "strings"
+ "testing"
+)
+
+func TestTitleToTypeDefinitions(t *testing.T) {
+ knownPrefixes := make(map[string]bool)
+ for _, def := range titleToType {
+ if len(def.includePrefixes) == 0 {
+ t.Errorf("title definition can't be empty")
+ }
+ for _, prefix := range def.includePrefixes {
+ if prefix == "" {
+ t.Errorf("title prefix can't be empty")
+ }
+ if knownPrefixes[prefix] {
+ t.Errorf("duplicate title prefix: %q", prefix)
+ }
+ if wasMatched, byPrefix := hasPrefix(knownPrefixes, prefix); wasMatched {
+ t.Errorf("%s was matched by %s", prefix, byPrefix)
+ }
+ knownPrefixes[prefix] = true
+ }
+ }
+}
+
+func hasPrefix(prefixes map[string]bool, s string) (bool, string) {
+ for prefix := range prefixes {
+ if strings.HasPrefix(s, prefix) {
+ return true, prefix
+ }
+ }
+ return false, ""
+}