From 77c702cf1a02ef4bb695e9daa9339afb3cbd5d89 Mon Sep 17 00:00:00 2001 From: Greg Steuck Date: Sat, 12 Jan 2019 13:20:22 -0800 Subject: sys/openbsd: avoid /dev/fd node creation Prevents corpus explosion with corrupted coverage data. The two parallel runs of: `doas ./syz-execprog -cover -coverfile /tmp/{fixed,unfixed} r.syz` show markedly different coverage pictures: unfixed: ``` 2019/01/12 13:55:38 parsed 1 programs 2019/01/12 13:55:38 executed programs: 0 2019/01/12 13:55:38 call #0: signal 821, coverage 2438 2019/01/12 13:55:38 call #1: signal 243, coverage 1363 2019/01/12 13:55:38 call #2: signal 502, coverage 1993 2019/01/12 13:55:38 call #3: signal 15, coverage 44 2019/01/12 13:55:38 call #4: signal 335, coverage 8196 ``` fixed: ``` 2019/01/12 13:51:57 parsed 1 programs 2019/01/12 13:51:57 executed programs: 0 2019/01/12 13:51:57 call #0: signal 837, coverage 2491 2019/01/12 13:51:57 call #1: signal 241, coverage 1341 2019/01/12 13:51:57 call #2: signal 27, coverage 61 2019/01/12 13:51:57 call #3: signal 13, coverage 44 2019/01/12 13:51:57 call #4: signal 39, coverage 299 ``` The contents of `r.syz` is ``` mknod(&(0x7f0000000180)='./file0\x00', 0x2006, 0x10000016e8) r0 = open(&(0x7f0000000100)='./file0\x00', 0x0, 0x0) mmap(&(0x7f0000000000/0x3000)=nil, 0x3000, 0x2, 0x10, r0, 0x0, 0x0) writev(0xffffffffffffffff, &(0x7f0000002480)=[{&(0x7f0000001480)="", 0x573}], 0x1) lstat(&(0x7f0000000240)='./file0\x00', &(0x7f0000000000)) ``` So, it's the final lstat which was getting that extra coverage. In particular, the end of unfixed.4 has some 4734 values 0xffffffff00000000. --- sys/openbsd/init.go | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/sys/openbsd/init.go b/sys/openbsd/init.go index 4dfb1a930..e36c8ae8d 100644 --- a/sys/openbsd/init.go +++ b/sys/openbsd/init.go @@ -25,20 +25,41 @@ type arch struct { S_IFCHR uint64 } +const ( + mknodMode = 0 + mknodDev = 1 + + // openbsd:src/etc/etc.amd64/MAKEDEV + devFdMajor = 22 + devNullDevT = 0x0202 +) + +func major(dev uint64) uint64 { + // openbsd:src/sys/sys/types.h + return (dev >> 8) & 0xff +} + func (arch *arch) SanitizeCall(c *prog.Call) { - // Prevent vnodes of type VBAD from being created. Such vnodes will - // likely trigger assertion errors by the kernel. - pos := 1 + argStart := 1 switch c.Meta.CallName { case "mknodat": - pos = 2 + argStart = 2 fallthrough case "mknod": - mode := c.Args[pos].(*prog.ConstArg) + // Prevent vnodes of type VBAD from being created. Such vnodes will + // likely trigger assertion errors by the kernel. + mode := c.Args[argStart+mknodMode].(*prog.ConstArg) if mode.Val&arch.S_IFMT == arch.S_IFMT { mode.Val &^= arch.S_IFMT mode.Val |= arch.S_IFCHR } + // Prevent /dev/fd/X devices from getting created. They interfere + // with kcov data collection and cause corpus explosion. + // https://groups.google.com/d/msg/syzkaller/_IRWeAjVoy4/Akl2XMZTDAAJ + mode = c.Args[argStart+mknodDev].(*prog.ConstArg) + if major(mode.Val) == devFdMajor { + mode.Val = devNullDevT + } default: arch.unix.SanitizeCall(c) } -- cgit mrf-deployment