From 872ebc286c4aa445b597066672a6082a9e724b0d Mon Sep 17 00:00:00 2001 From: Anton Lindqvist Date: Thu, 13 Aug 2020 10:01:33 +0200 Subject: sys/openbsd: neutralize sysctl kern.maxthread Yet another root only knob that can cause the syz-execprog process to panic[1]. Greg is currently working on sanitizing sysctl integer knobs in the OpenBSD kernel. This will improve the situation but preventing fiddling with this knob is a good call anyway. While here, restructure the code a bit making it easier to add sysctl neutralizers. [1] https://syzkaller.appspot.com/bug?id=40bcbbeb244998dfc4eeec90b8f8bce372882211 --- sys/openbsd/init.go | 43 ++++++++++++++++++++++++++++++++++++------- sys/openbsd/init_test.go | 9 +++++++-- 2 files changed, 43 insertions(+), 9 deletions(-) (limited to 'sys/openbsd') diff --git a/sys/openbsd/init.go b/sys/openbsd/init.go index 9b6e68ed1..c7e624090 100644 --- a/sys/openbsd/init.go +++ b/sys/openbsd/init.go @@ -19,6 +19,7 @@ func InitTarget(target *prog.Target) { DIOCCLRSTATES: target.GetConst("DIOCCLRSTATES"), DIOCKILLSTATES: target.GetConst("DIOCKILLSTATES"), KERN_MAXCLUSTERS: target.GetConst("KERN_MAXCLUSTERS"), + KERN_MAXTHREAD: target.GetConst("KERN_MAXTHREAD"), S_IFCHR: target.GetConst("S_IFCHR"), S_IFMT: target.GetConst("S_IFMT"), MCL_FUTURE: target.GetConst("MCL_FUTURE"), @@ -38,6 +39,7 @@ type arch struct { DIOCCLRSTATES uint64 DIOCKILLSTATES uint64 KERN_MAXCLUSTERS uint64 + KERN_MAXTHREAD uint64 S_IFCHR uint64 S_IFMT uint64 MCL_FUTURE uint64 @@ -206,19 +208,46 @@ func (arch *arch) neutralizeSysctl(c *prog.Call) { return } - mib := ptr.Res.(*prog.GroupArg).Inner - if len(mib) < 2 { + var mib []*prog.ConstArg + for _, arg := range ptr.Res.(*prog.GroupArg).Inner { + switch v := arg.(type) { + case *prog.ConstArg: + mib = append(mib, v) + } + } + + if !arch.neutralizeSysctlKern(mib) { return } - n1 := mib[0].(*prog.ConstArg) - n2 := mib[1].(*prog.ConstArg) + for _, m := range mib { + m.Val = 0 + } + // Reflect changes in the namelen argument. + if len(c.Args) >= 1 { + switch v := c.Args[1].(type) { + case *prog.ConstArg: + v.Val = 0 + } + } +} + +func (arch *arch) neutralizeSysctlKern(mib []*prog.ConstArg) bool { // Do not fiddle with root only knob kern.maxclusters, one of the causes // of "no output from test machine" reports. - if n1.Val == arch.CTL_KERN && n2.Val == arch.KERN_MAXCLUSTERS { - n1.Val = 0 - n2.Val = 0 + if len(mib) >= 2 && + mib[0].Val == arch.CTL_KERN && mib[1].Val == arch.KERN_MAXCLUSTERS { + return true } + + // Do not fiddle with root only knob kern.maxthread, can cause the + // syz-execprog process to panic. + if len(mib) >= 2 && + mib[0].Val == arch.CTL_KERN && mib[1].Val == arch.KERN_MAXTHREAD { + return true + } + + return false } func (arch *arch) annotateCall(c prog.ExecCall) string { diff --git a/sys/openbsd/init_test.go b/sys/openbsd/init_test.go index d749acc09..7f3d9a489 100644 --- a/sys/openbsd/init_test.go +++ b/sys/openbsd/init_test.go @@ -83,10 +83,15 @@ func TestNeutralize(t *testing.T) { In: `setrlimit(0x0, &(0x7f0000cc0ff0)={0x1, 0x1})`, }, { - // CTL_KERN, KERN_MAXCLUSTERS - In: `sysctl$kern(&(0x7f0000cc0ff0)={0x1, 0x43}, 0x0, 0x0, 0x0, &(0x7f0000000180), 0x0)`, + // Test for sysctl kern.maxclusters. + In: `sysctl$kern(&(0x7f0000cc0ff0)={0x1, 0x43}, 0x2, 0x0, 0x0, &(0x7f0000000180), 0x0)`, Out: `sysctl$kern(&(0x7f0000cc0ff0)={0x0}, 0x0, 0x0, 0x0, &(0x7f0000000180), 0x0)`, }, + { + // Test for sysctl kern.maxthread. + In: `sysctl$kern(&(0x7f0000000300)={0x1, 0x19}, 0x2, 0x0, 0x0, &(0x7f0000000300)="ff0380c5", 0x4)`, + Out: `sysctl$kern(&(0x7f0000000300)={0x0}, 0x0, 0x0, 0x0, &(0x7f0000000300)="ff0380c5", 0x4)`, + }, { In: `clock_settime(0x0, &(0x7f0000cc0ff0)={0x0, 0x0})`, Out: `clock_settime(0xffffffffffffffff, &(0x7f0000cc0ff0))`, -- cgit mrf-deployment