aboutsummaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorGreg Steuck <gnezdo@google.com>2019-01-12 13:20:22 -0800
committerDmitry Vyukov <dvyukov@google.com>2019-01-14 09:48:45 +0100
commit77c702cf1a02ef4bb695e9daa9339afb3cbd5d89 (patch)
treeaeedbb9480a51758ff791b9c584b1fc278d34c8c /sys
parentc3f3344c78d6f69e1494297262c453f8ed10a844 (diff)
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)="<junk>", 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.
Diffstat (limited to 'sys')
-rw-r--r--sys/openbsd/init.go31
1 files 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)
}