diff options
| author | Greg Steuck <gnezdo@google.com> | 2019-01-12 13:20:22 -0800 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2019-01-14 09:48:45 +0100 |
| commit | 77c702cf1a02ef4bb695e9daa9339afb3cbd5d89 (patch) | |
| tree | aeedbb9480a51758ff791b9c584b1fc278d34c8c | |
| parent | c3f3344c78d6f69e1494297262c453f8ed10a844 (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.
| -rw-r--r-- | sys/openbsd/init.go | 31 |
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) } |
