aboutsummaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/openbsd/init.go41
-rw-r--r--sys/openbsd/init_test.go50
2 files changed, 86 insertions, 5 deletions
diff --git a/sys/openbsd/init.go b/sys/openbsd/init.go
index 4dfb1a930..cb277ee3e 100644
--- a/sys/openbsd/init.go
+++ b/sys/openbsd/init.go
@@ -25,20 +25,51 @@ type arch struct {
S_IFCHR uint64
}
+const (
+ mknodMode = 0
+ mknodDev = 1
+
+ // openbsd:src/etc/etc.amd64/MAKEDEV
+ devFdMajor = 22
+ devNullDevT = 0x0202
+
+ // kCoverFd in executor/executor.cc
+ kcovFdMinorMin = 232
+ // kOutPipeFd in executor/executor.cc
+ kcovFdMinorMax = 248
+)
+
+func isKcovFd(dev uint64) bool {
+ // openbsd:src/sys/sys/types.h
+ major := (dev >> 8) & 0xff
+ minor := (dev & 0xff) | ((dev & 0xffff0000) >> 8)
+
+ return major == devFdMajor && minor >= kcovFdMinorMin && minor < kcovFdMinorMax
+}
+
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 where X maps
+ // to an open kcov fd. They interfere with kcov data collection
+ // and cause corpus explosion.
+ // https://groups.google.com/d/msg/syzkaller/_IRWeAjVoy4/Akl2XMZTDAAJ
+ dev := c.Args[argStart+mknodDev].(*prog.ConstArg)
+ if isKcovFd(dev.Val) {
+ dev.Val = devNullDevT
+ }
default:
arch.unix.SanitizeCall(c)
}
diff --git a/sys/openbsd/init_test.go b/sys/openbsd/init_test.go
new file mode 100644
index 000000000..780fe3efb
--- /dev/null
+++ b/sys/openbsd/init_test.go
@@ -0,0 +1,50 @@
+package openbsd_test
+
+import (
+ "fmt"
+ "strings"
+ "testing"
+
+ "github.com/google/syzkaller/prog"
+ _ "github.com/google/syzkaller/sys/openbsd/gen"
+)
+
+func TestSanitizeMknodCall(t *testing.T) {
+ target, err := prog.GetTarget("openbsd", "amd64")
+ if err != nil {
+ t.Fatal(err)
+ }
+ tests := []struct {
+ input string
+ output string
+ }{
+ {
+ // major=22, minor=232
+ `mknodat(0x0, 0x0, 0x0, 0x16e8)`,
+ `mknodat(0x0, 0x0, 0x0, 0x202)`,
+ },
+ {
+ // major=22, minor=232
+ `mknod(0x0, 0x0, 0x16e8)`,
+ `mknod(0x0, 0x0, 0x202)`,
+ },
+ {
+ // major=22, minor=0
+ `mknod(0x0, 0x0, 0x1600)`,
+ `mknod(0x0, 0x0, 0x1600)`,
+ },
+ }
+ for i, test := range tests {
+ t.Run(fmt.Sprint(i), func(t *testing.T) {
+ p, err := target.Deserialize([]byte(test.input), prog.Strict)
+ if err != nil {
+ t.Fatal(err)
+ }
+ got := strings.TrimSpace(string(p.Serialize()))
+ want := strings.TrimSpace(test.output)
+ if got != want {
+ t.Fatalf("input:\n%v\ngot:\n%v\nwant:\n%s", test.input, got, want)
+ }
+ })
+ }
+}