diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2022-01-19 15:18:52 +0000 |
|---|---|---|
| committer | Aleksandr Nogikh <wp32pw@gmail.com> | 2022-01-20 16:29:05 +0100 |
| commit | ab3d9f17d3b73b74f89b4ea3bd951e09ab4149a8 (patch) | |
| tree | 68ff87a34750915492e2d1f20060a6d2b961f8ef /sys/linux/init.go | |
| parent | b838eb76eef06deea9b4ec66dd328e77ca00eb0f (diff) | |
sys/linux: neutralize sched_setattr
Setting itself or another process as a real-time one leads to the
starvation of kernel threads and, as a result, to false positive stall
bug reports. We have been getting complaints about them for already
quite a long time now.
Neutralize the policy argument of the syscall as much as possible given
the set of possible syzkaller mutations.
Diffstat (limited to 'sys/linux/init.go')
| -rw-r--r-- | sys/linux/init.go | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/sys/linux/init.go b/sys/linux/init.go index 88bfe919e..6fa9665a8 100644 --- a/sys/linux/init.go +++ b/sys/linux/init.go @@ -230,6 +230,9 @@ func (arch *arch) neutralize(c *prog.Call) { enforceIntArg(c.Args[0]) enforceIntArg(c.Args[1]) enforceIntArg(c.Args[2]) + case "sched_setattr": + // Enabling a SCHED_FIFO or a SCHED_RR policy may lead to false positive stall-related crashes. + neutralizeSchedAttr(c.Args[1]) } switch c.Meta.Name { @@ -238,6 +241,52 @@ func (arch *arch) neutralize(c *prog.Call) { } } +func neutralizeSchedAttr(a prog.Arg) { + switch attr := a.(type) { + case *prog.PointerArg: + if attr.Res == nil { + // If it's just a pointer to somewhere, still set it to NULL as there's a risk that + // it points to the valid memory and it can be interpreted as a sched_attr struct. + attr.Address = 0 + return + } + groupArg, ok := attr.Res.(*prog.GroupArg) + if !ok || len(groupArg.Inner) == 0 { + return + } + if unionArg, ok := groupArg.Inner[0].(*prog.UnionArg); ok { + dataArg, ok := unionArg.Option.(*prog.DataArg) + if !ok { + return + } + if dataArg.Dir() == prog.DirOut { + return + } + // Clear the first 16 bytes to prevent overcoming the limitation by squashing the struct. + data := append([]byte{}, dataArg.Data()...) + for i := 0; i < 16 && i < len(data); i++ { + data[i] = 0 + } + dataArg.SetData(data) + } + + // Most likely it's the intended sched_attr structure. + if len(groupArg.Inner) > 1 { + policyField, ok := groupArg.Inner[1].(*prog.ConstArg) + if !ok { + return + } + const SCHED_FIFO = 0x1 + const SCHED_RR = 0x2 + if policyField.Val == SCHED_FIFO || policyField.Val == SCHED_RR { + policyField.Val = 0 + } + } + case *prog.ConstArg: + attr.Val = 0 + } +} + func enforceIntArg(a prog.Arg) { arg, ok := a.(*prog.ConstArg) if !ok { |
