mirror of
https://github.com/reactos/syzkaller.git
synced 2024-11-27 21:30:33 +00:00
pkg/report: fix guilty file extraction
Account for the case that some file names can appear _before_ crash report starts. Start extracting guilty file starting from StartPos.
This commit is contained in:
parent
455b6354e8
commit
db716d6653
@ -27,7 +27,7 @@ type linux struct {
|
||||
consoleOutputRe *regexp.Regexp
|
||||
questionableRe *regexp.Regexp
|
||||
guiltyFileBlacklist []*regexp.Regexp
|
||||
reportStartIgnores [][]byte
|
||||
reportStartIgnores []*regexp.Regexp
|
||||
infoMessagesWithStack [][]byte
|
||||
eoi []byte
|
||||
}
|
||||
@ -82,10 +82,10 @@ func ctorLinux(kernelSrc, kernelObj string, ignores []*regexp.Regexp) (Reporter,
|
||||
regexp.MustCompile(`^fs/proc/generic.c`),
|
||||
}
|
||||
// These pattern do _not_ start a new report, i.e. can be in a middle of another report.
|
||||
ctx.reportStartIgnores = [][]byte{
|
||||
[]byte("invalid opcode: 0000"),
|
||||
[]byte("Kernel panic - not syncing: panic_on_warn set"),
|
||||
[]byte("unregister_netdevice: waiting for"),
|
||||
ctx.reportStartIgnores = []*regexp.Regexp{
|
||||
compile(`invalid opcode: 0000`),
|
||||
compile(`Kernel panic - not syncing: panic_on_warn set`),
|
||||
compile(`unregister_netdevice: waiting for`),
|
||||
}
|
||||
// These pattern math kernel reports which are not bugs in itself but contain stack traces.
|
||||
// If we see them in the middle of another report, we know that the report is potentially corrupted.
|
||||
@ -200,14 +200,7 @@ func (ctx *linux) parseOutput(output []byte) (
|
||||
startPos = pos
|
||||
break
|
||||
} else if secondReportPos == 0 {
|
||||
ignored := false
|
||||
for _, ignore := range ctx.reportStartIgnores {
|
||||
if bytes.Contains(line, ignore) {
|
||||
ignored = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !ignored {
|
||||
if !matchesAny(line, ctx.reportStartIgnores) {
|
||||
secondReportPos = pos
|
||||
}
|
||||
}
|
||||
@ -274,20 +267,22 @@ func (ctx *linux) parseOutput(output []byte) (
|
||||
}
|
||||
|
||||
func (ctx *linux) Symbolize(rep *Report) error {
|
||||
if ctx.vmlinux == "" {
|
||||
return nil
|
||||
}
|
||||
symbolized, err := ctx.symbolize(rep.Report)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rep.Report = symbolized
|
||||
guiltyFile := ctx.extractGuiltyFile(rep.Report)
|
||||
if guiltyFile != "" {
|
||||
rep.Maintainers, err = ctx.getMaintainers(guiltyFile)
|
||||
if ctx.vmlinux != "" {
|
||||
symbolized, err := ctx.symbolize(rep.Report)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rep.Report = symbolized
|
||||
}
|
||||
// We still do this even if we did not symbolize,
|
||||
// because tests pass in already symbolized input.
|
||||
rep.guiltyFile = ctx.extractGuiltyFile(rep)
|
||||
if rep.guiltyFile != "" {
|
||||
maintainers, err := ctx.getMaintainers(rep.guiltyFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rep.Maintainers = maintainers
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -381,7 +376,8 @@ func symbolizeLine(symbFunc func(bin string, pc uint64) ([]symbolizer.Frame, err
|
||||
return symbolized
|
||||
}
|
||||
|
||||
func (ctx *linux) extractGuiltyFile(report []byte) string {
|
||||
func (ctx *linux) extractGuiltyFile(rep *Report) string {
|
||||
report := rep.Report[rep.StartPos:]
|
||||
if linuxRcuStall.Match(report) {
|
||||
// Special case for rcu stalls.
|
||||
// There are too many frames that we want to skip before actual guilty frames,
|
||||
@ -412,6 +408,9 @@ nextFile:
|
||||
}
|
||||
|
||||
func (ctx *linux) getMaintainers(file string) ([]string, error) {
|
||||
if ctx.kernelSrc == "" {
|
||||
return nil, nil
|
||||
}
|
||||
mtrs, err := ctx.getMaintainersImpl(file, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -43,8 +43,10 @@ type Report struct {
|
||||
Corrupted bool
|
||||
// CorruptedReason contains reason why the report is marked as corrupted.
|
||||
CorruptedReason string
|
||||
// Maintainers is list of maintainer emails.
|
||||
// Maintainers is list of maintainer emails (filled in by Symbolize).
|
||||
Maintainers []string
|
||||
// guiltyFile is the source file that we think is to blame for the crash (filled in by Symbolize).
|
||||
guiltyFile string
|
||||
}
|
||||
|
||||
// NewReporter creates reporter for the specified OS/Type.
|
||||
@ -189,17 +191,6 @@ func sanitizeTitle(title string) string {
|
||||
return strings.TrimSpace(string(res))
|
||||
}
|
||||
|
||||
type guilter interface {
|
||||
extractGuiltyFile([]byte) string
|
||||
}
|
||||
|
||||
func (wrap reporterWrapper) extractGuiltyFile(report []byte) string {
|
||||
if g, ok := wrap.Reporter.(guilter); ok {
|
||||
return g.extractGuiltyFile(report)
|
||||
}
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
type oops struct {
|
||||
header []byte
|
||||
formats []oopsFormat
|
||||
|
@ -220,8 +220,26 @@ func testGuiltyFile(t *testing.T, reporter Reporter, fn string) {
|
||||
}
|
||||
file := string(data[len(prefix) : len(prefix)+nlnl])
|
||||
report := data[len(prefix)+nlnl:]
|
||||
if guilty := reporter.(guilter).extractGuiltyFile(report); guilty != file {
|
||||
t.Fatalf("got guilty %q, want %q", guilty, file)
|
||||
rep := reporter.Parse(report)
|
||||
if rep == nil {
|
||||
t.Fatalf("did not find crash in the input")
|
||||
}
|
||||
// Parse doesn't generally run on already symbolized output,
|
||||
// but here we run it on symbolized output because we can't symbolize in tests.
|
||||
// The problem is with duplicated lines due to inlined frames,
|
||||
// Parse can strip such report after first title line because it thinks
|
||||
// that the duplicated title line is beginning on another report.
|
||||
// In such case we restore whole report, but still keep StartPos that
|
||||
// Parse produces at least in some cases.
|
||||
if !bytes.HasSuffix(report, rep.Report) {
|
||||
rep.Report = report
|
||||
rep.StartPos = 0
|
||||
}
|
||||
if err := reporter.Symbolize(rep); err != nil {
|
||||
t.Fatalf("failed to symbolize report: %v", err)
|
||||
}
|
||||
if rep.guiltyFile != file {
|
||||
t.Fatalf("got guilty %q, want %q", rep.guiltyFile, file)
|
||||
}
|
||||
}
|
||||
|
||||
|
1
pkg/report/testdata/linux/guilty/20
vendored
1
pkg/report/testdata/linux/guilty/20
vendored
@ -1,3 +1,4 @@
|
||||
FILE: driver/foo/lib/foo.c
|
||||
|
||||
WARNING: CPU: 2 PID: 24023 at kernel/locking/lockdep.c:3344 __lock_acquire+0x10e5/0x3690 kernel/locking/lockdep.c:3344
|
||||
driver/foo/lib/foo.c:10
|
||||
|
77
pkg/report/testdata/linux/guilty/39
vendored
Normal file
77
pkg/report/testdata/linux/guilty/39
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
FILE: security/apparmor/policy_ns.c
|
||||
|
||||
sock_common_setsockopt+0x9a/0xe0 net/core/sock.c:3038
|
||||
__sys_setsockopt+0x1ba/0x3c0 net/socket.c:1902
|
||||
__do_sys_setsockopt net/socket.c:1913 [inline]
|
||||
__se_sys_setsockopt net/socket.c:1910 [inline]
|
||||
__x64_sys_setsockopt+0xbe/0x150 net/socket.c:1910
|
||||
do_syscall_64+0x1b9/0x820 arch/x86/entry/common.c:290
|
||||
==================================================================
|
||||
BUG: KASAN: global-out-of-bounds in memcmp+0xe3/0x160 lib/string.c:861
|
||||
Read of size 1 at addr ffffffff88000008 by task syz-executor0/10914
|
||||
|
||||
entry_SYSCALL_64_after_hwframe+0x49/0xbe
|
||||
RIP: 0033:0x457579
|
||||
Code: 1d b4 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 eb b3 fb ff c3 66 2e 0f 1f 84 00 00 00 00
|
||||
RSP: 002b:00007f4c14533c78 EFLAGS: 00000246 ORIG_RAX: 0000000000000036
|
||||
RAX: ffffffffffffffda RBX: 00007f4c14533c90 RCX: 0000000000457579
|
||||
RDX: 0000000000000040 RSI: 0000000000000000 RDI: 0000000000000003
|
||||
RBP: 000000000072bf00 R08: 0000000000000004 R09: 0000000000000000
|
||||
R10: 0000000020000080 R11: 0000000000000246 R12: 00007f4c145346d4
|
||||
R13: 00000000004c3ed9 R14: 00000000004d6260 R15: 0000000000000004
|
||||
CPU: 0 PID: 10914 Comm: syz-executor0 Not tainted 4.19.0-rc5+ #252
|
||||
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
|
||||
Call Trace:
|
||||
__dump_stack lib/dump_stack.c:77 [inline]
|
||||
dump_stack+0x1c4/0x2b4 lib/dump_stack.c:113
|
||||
print_address_description.cold.8+0x58/0x1ff mm/kasan/report.c:256
|
||||
kasan_report_error mm/kasan/report.c:354 [inline]
|
||||
kasan_report.cold.9+0x242/0x309 mm/kasan/report.c:412
|
||||
__asan_report_load1_noabort+0x14/0x20 mm/kasan/report.c:430
|
||||
memcmp+0xe3/0x160 lib/string.c:861
|
||||
strnstr+0x4b/0x70 lib/string.c:934
|
||||
__aa_lookupn_ns+0xc1/0x570 security/apparmor/policy_ns.c:209
|
||||
aa_lookupn_ns+0x88/0x1e0 security/apparmor/policy_ns.c:240
|
||||
aa_fqlookupn_profile+0x1b9/0x1010 security/apparmor/policy.c:468
|
||||
fqlookupn_profile+0x80/0xc0 security/apparmor/label.c:1844
|
||||
aa_label_strn_parse+0xa3a/0x1230 security/apparmor/label.c:1908
|
||||
aa_label_parse+0x42/0x50 security/apparmor/label.c:1943
|
||||
aa_change_profile+0x513/0x3510 security/apparmor/domain.c:1362
|
||||
apparmor_setprocattr+0xa8b/0x1150 security/apparmor/lsm.c:656
|
||||
security_setprocattr+0x66/0xc0 security/security.c:1298
|
||||
proc_pid_attr_write+0x301/0x540 fs/proc/base.c:2555
|
||||
__vfs_write+0x119/0x9f0 fs/read_write.c:485
|
||||
vfs_write+0x1fc/0x560 fs/read_write.c:549
|
||||
ksys_write+0x101/0x260 fs/read_write.c:598
|
||||
__do_sys_write fs/read_write.c:610 [inline]
|
||||
__se_sys_write fs/read_write.c:607 [inline]
|
||||
__x64_sys_write+0x73/0xb0 fs/read_write.c:607
|
||||
do_syscall_64+0x1b9/0x820 arch/x86/entry/common.c:290
|
||||
entry_SYSCALL_64_after_hwframe+0x49/0xbe
|
||||
RIP: 0033:0x457579
|
||||
Code: 1d b4 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 eb b3 fb ff c3 66 2e 0f 1f 84 00 00 00 00
|
||||
RSP: 002b:00007f5a92ec2c78 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
|
||||
RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 0000000000457579
|
||||
RDX: 000000000000002c RSI: 00000000200000c0 RDI: 0000000000000004
|
||||
RBP: 000000000072bf00 R08: 0000000000000000 R09: 0000000000000000
|
||||
R10: 0000000000000000 R11: 0000000000000246 R12: 00007f5a92ec36d4
|
||||
R13: 00000000004c5454 R14: 00000000004d8c78 R15: 00000000ffffffff
|
||||
|
||||
CPU: 1 PID: 10921 Comm: syz-executor3 Not tainted 4.19.0-rc5+ #252
|
||||
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
|
||||
The buggy address belongs to the variable:
|
||||
__start_rodata+0x8/0x1000
|
||||
Call Trace:
|
||||
__dump_stack lib/dump_stack.c:77 [inline]
|
||||
dump_stack+0x1c4/0x2b4 lib/dump_stack.c:113
|
||||
|
||||
Memory state around the buggy address:
|
||||
ffffffff87ffff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
ffffffff87ffff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
fail_dump lib/fault-inject.c:51 [inline]
|
||||
should_fail.cold.4+0xa/0x17 lib/fault-inject.c:149
|
||||
ffffffff88000000: 00 fa fa fa fa fa fa fa 00 01 fa fa fa fa fa fa
|
||||
^
|
||||
ffffffff88000080: 00 00 00 07 fa fa fa fa 00 04 fa fa fa fa fa fa
|
||||
ffffffff88000100: 05 fa fa fa fa fa fa fa 00 00 00 00 05 fa fa fa
|
||||
==================================================================
|
Loading…
Reference in New Issue
Block a user