From 0e3f16adacdcd0c286a83814317bc862a7acd332 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Wed, 15 Feb 2017 15:52:52 +0100 Subject: 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. --- report/report.go | 55 ++++++++++++++++++++++++++++++++++++++++++++------- report/report_test.go | 45 ++++++++++++++++++++++++++++++++++++++++- 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 @@ -38,6 +38,10 @@ var oopses = []*oops{ compile("BUG: KASAN: ([a-z\\-]+) on address(?:.*\\n)+?.*(Read|Write) of size ([0-9]+)"), "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", @@ -189,6 +193,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("") ) @@ -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 @@ -534,6 +534,30 @@ INFO: Stall ended before state dump start 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 @@ -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 `, @@ -639,6 +665,23 @@ executing program 1: 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 { -- cgit mrf-deployment