aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2017-02-15 15:52:52 +0100
committerDmitry Vyukov <dvyukov@google.com>2017-02-15 15:52:52 +0100
commit0e3f16adacdcd0c286a83814317bc862a7acd332 (patch)
treed7ce21cf4a1a806dab8cf3610b97768740770d63
parente0e9f890f2df95843b785ba954dc78ecacfa0fe9 (diff)
report: assorted improvements to report parsing
1. Keep up to 5 lines before report (can contain important context). 2. Replace addresses/cpu numbers/PIDs/etc with constant strings. 3. Add regexp for android double-free.
-rw-r--r--report/report.go55
-rw-r--r--report/report_test.go45
2 files changed, 92 insertions, 8 deletions
diff --git a/report/report.go b/report/report.go
index 1151c6133..97095ab63 100644
--- a/report/report.go
+++ b/report/report.go
@@ -39,6 +39,10 @@ var oopses = []*oops{
"KASAN: %[1]v %[2]v of size %[3]v",
},
{
+ compile("BUG: KASAN: (.*)"),
+ "KASAN: %[1]v",
+ },
+ {
compile("BUG: unable to handle kernel paging request(?:.*\\n)+?.*IP: {{PC}} +{{FUNC}}"),
"BUG: unable to handle kernel paging request in %[1]v",
},
@@ -190,6 +194,16 @@ var oopses = []*oops{
[]*regexp.Regexp{},
},
&oops{
+ []byte("BUG kmalloc-"),
+ []oopsFormat{
+ {
+ compile("BUG kmalloc-.*: Object already free"),
+ "BUG: Object already free",
+ },
+ },
+ []*regexp.Regexp{},
+ },
+ &oops{
[]byte("divide error:"),
[]oopsFormat{
{
@@ -238,6 +252,10 @@ var (
consoleOutputRe = regexp.MustCompile(`^(?:\<[0-9]+\>)?\[ *[0-9]+\.[0-9]+\] `)
questionableRe = regexp.MustCompile(`(?:\[\<[0-9a-f]+\>\])? \? +[a-zA-Z0-9_.]+\+0x[0-9a-f]+/[0-9a-f]+`)
symbolizeRe = regexp.MustCompile(`(?:\[\<(?:[0-9a-f]+)\>\])? +(?:[0-9]+:)?([a-zA-Z0-9_.]+)\+0x([0-9a-f]+)/0x([0-9a-f]+)`)
+ addrRe = regexp.MustCompile(`[0-9a-f]{16}`)
+ funcRe = regexp.MustCompile(`([a-zA-Z][a-zA-Z0-9_.]+)\+0x[0-9a-z]+/0x[0-9a-z]+`)
+ cpuRe = regexp.MustCompile(`CPU#[0-9]+`)
+ executorRe = regexp.MustCompile(`syz-executor[0-9]+(/|:)[0-9]+`)
eoi = []byte("<EOI>")
)
@@ -276,6 +294,7 @@ func ContainsCrash(output []byte, ignores []*regexp.Regexp) bool {
// start and end denote region of output with oops message(s).
func Parse(output []byte, ignores []*regexp.Regexp) (desc string, text []byte, start int, end int) {
var oops *oops
+ var textPrefix [][]byte
for pos := 0; pos < len(output); {
next := bytes.IndexByte(output[pos:], '\n')
if next != -1 {
@@ -295,14 +314,26 @@ func Parse(output []byte, ignores []*regexp.Regexp) (desc string, text []byte, s
}
end = next
}
- if oops != nil {
- if consoleOutputRe.Match(output[pos:next]) &&
- (!questionableRe.Match(output[pos:next]) || bytes.Index(output[pos:next], eoi) != -1) {
- lineStart := bytes.Index(output[pos:next], []byte("] ")) + pos + 2
- lineEnd := next
- if lineEnd != 0 && output[lineEnd-1] == '\r' {
- lineEnd--
+ if consoleOutputRe.Match(output[pos:next]) &&
+ (!questionableRe.Match(output[pos:next]) || bytes.Index(output[pos:next], eoi) != -1) {
+ lineStart := bytes.Index(output[pos:next], []byte("] ")) + pos + 2
+ lineEnd := next
+ if lineEnd != 0 && output[lineEnd-1] == '\r' {
+ lineEnd--
+ }
+ if oops == nil {
+ textPrefix = append(textPrefix, append([]byte{}, output[lineStart:lineEnd]...))
+ if len(textPrefix) > 5 {
+ textPrefix = textPrefix[1:]
+ }
+ } else {
+ // Prepend 5 lines preceding start of the report,
+ // they can contain additional info related to the report.
+ for _, prefix := range textPrefix {
+ text = append(text, prefix...)
+ text = append(text, '\n')
}
+ textPrefix = nil
text = append(text, output[lineStart:lineEnd]...)
text = append(text, '\n')
}
@@ -316,6 +347,16 @@ func Parse(output []byte, ignores []*regexp.Regexp) (desc string, text []byte, s
if len(desc) > 0 && desc[len(desc)-1] == '\r' {
desc = desc[:len(desc)-1]
}
+ // Replace that everything looks like an address with "ADDR",
+ // addresses in descriptions can't be good regardless of the oops regexps.
+ desc = addrRe.ReplaceAllLiteralString(desc, "ADDR")
+ // Replace all raw references to runctions (e.g. "ip6_fragment+0x1052/0x2d80")
+ // with just function name ("ip6_fragment"). Offsets and sizes are not stable.
+ desc = funcRe.ReplaceAllString(desc, "$1")
+ // CPU numbers are not interesting.
+ desc = cpuRe.ReplaceAllLiteralString(desc, "CPU")
+ // Executor PIDs are not interesting.
+ desc = executorRe.ReplaceAllLiteralString(desc, "syz-executor")
// Corrupted/intermixed lines can be very long.
const maxDescLen = 180
if len(desc) > maxDescLen {
diff --git a/report/report_test.go b/report/report_test.go
index 67b5898ce..82ce82818 100644
--- a/report/report_test.go
+++ b/report/report_test.go
@@ -535,6 +535,30 @@ WARNING: /etc/ssh/moduli does not exist, using fixed modulus
`: ``,
`
+[ 1579.244514] BUG: KASAN: slab-out-of-bounds in ip6_fragment+0x1052/0x2d80 at addr ffff88004ec29b58
+`: `KASAN: slab-out-of-bounds in ip6_fragment at addr ADDR`,
+
+ `
+[ 982.271203] BUG: spinlock bad magic on CPU#0, syz-executor12/24932
+`: `BUG: spinlock bad magic on CPU, syz-executor`,
+
+ `
+[ 374.860710] BUG: KASAN: use-after-free in do_con_write.part.23+0x1c50/0x1cb0 at addr ffff88000012c43a
+`: `KASAN: use-after-free in do_con_write.part.23 at addr ADDR`,
+
+ `
+[ 163.314570] WARNING: kernel stack regs at ffff8801d100fea8 in syz-executor1:16059 has bad 'bp' value ffff8801d100ff28
+`: `WARNING: kernel stack regs at ADDR in syz-executor has bad 'bp' value ADDR`,
+
+ `
+[ 76.825838] BUG: using __this_cpu_add() in preemptible [00000000] code: syz-executor0/10076
+`: `BUG: using __this_cpu_add() in preemptible [00000000] code: syz-executor`,
+
+ `
+[ 367.131148] BUG kmalloc-8 (Tainted: G B ): Object already free
+`: `BUG: Object already free`,
+
+ `
[ 92.396607] APIC base relocation is unsupported by KVM
[ 95.445015] INFO: NMI handler (perf_event_nmi_handler) took too long to run: 1.356 msecs
[ 95.445015] perf: interrupt took too long (3985 > 3976), lowering kernel.perf_event_max_sample_rate to 50000
@@ -625,7 +649,9 @@ getsockopt$NETROM_N2(r2, 0x103, 0x3, &(0x7f00008de000-0x4)=0x1, &(0x7f00008dd000
[ 536.429346] NMI watchdog: BUG: soft lockup - CPU#1 stuck for 11s! [syz-executor7:16813]
mmap(&(0x7f0000557000/0x2000)=nil, (0x2000), 0x1, 0x11, r2, 0x1b)
[ 536.437530] Modules linked in:
-[ 536.440808] CPU: 1 PID: 16813 Comm: syz-executor7 Not tainted 4.3.5-smp-DEV #119`: `NMI watchdog: BUG: soft lockup - CPU#1 stuck for 11s! [syz-executor7:16813]
+[ 536.440808] CPU: 1 PID: 16813 Comm: syz-executor7 Not tainted 4.3.5-smp-DEV #119`: `nla_parse: 5 callbacks suppressed
+netlink: 3 bytes leftover after parsing attributes in process 'syz-executor5'.
+NMI watchdog: BUG: soft lockup - CPU#1 stuck for 11s! [syz-executor7:16813]
Modules linked in:
CPU: 1 PID: 16813 Comm: syz-executor7 Not tainted 4.3.5-smp-DEV #119
`,
@@ -640,6 +666,23 @@ nouveau [ DRM] suspending kernel object tree...
nouveau [ DRM] nouveau suspended
init: computing context for service 'clear-bcb'
`,
+
+ `[ 94.864848] line 0
+[ 94.864848] line 1
+[ 94.864848] line 2
+[ 94.864848] line 3
+[ 94.864848] line 4
+[ 94.864848] line 5
+[ 95.145581] ==================================================================
+[ 95.152992] BUG: KASAN: use-after-free in snd_seq_queue_alloc+0x670/0x690 at addr ffff8801d0c6b080
+[ 95.162080] Read of size 4 by task syz-executor2/5764`: `line 2
+line 3
+line 4
+line 5
+==================================================================
+BUG: KASAN: use-after-free in snd_seq_queue_alloc+0x670/0x690 at addr ffff8801d0c6b080
+Read of size 4 by task syz-executor2/5764
+`,
}
for log, text0 := range tests {
if desc, text, _, _ := Parse([]byte(log), nil); string(text) != text0 {