From 86e1b94111c3338977824bb2f6b335adeb5b0a8a Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Mon, 10 May 2021 12:51:03 +0200 Subject: syz-fuzzer: check incoming programs for disabled syscalls Ensure that incoming programs don't contain disabled syscalls. Manager should not send such programs, but we are still seeing some episodic unexplainable "executing disabled syscall" panics and it's unclear how this happens. --- syz-fuzzer/fuzzer.go | 20 ++++++++++++++++++++ syz-fuzzer/proc.go | 21 +-------------------- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/syz-fuzzer/fuzzer.go b/syz-fuzzer/fuzzer.go index 0f51932df..8a1b932d9 100644 --- a/syz-fuzzer/fuzzer.go +++ b/syz-fuzzer/fuzzer.go @@ -457,12 +457,32 @@ func (fuzzer *Fuzzer) deserializeInput(inp []byte) *prog.Prog { if err != nil { log.Fatalf("failed to deserialize prog: %v\n%s", err, inp) } + fuzzer.checkDisabledCalls(p) if len(p.Calls) > prog.MaxCalls { return nil } return p } +func (fuzzer *Fuzzer) checkDisabledCalls(p *prog.Prog) { + for _, call := range p.Calls { + if !fuzzer.choiceTable.Enabled(call.Meta.ID) { + fmt.Printf("executing disabled syscall %v [%v]\n", call.Meta.Name, call.Meta.ID) + sandbox := ipc.FlagsToSandbox(fuzzer.config.Flags) + fmt.Printf("check result for sandbox=%v:\n", sandbox) + for _, id := range fuzzer.checkResult.EnabledCalls[sandbox] { + meta := fuzzer.target.Syscalls[id] + fmt.Printf(" %v [%v]\n", meta.Name, meta.ID) + } + fmt.Printf("choice table:\n") + for i, meta := range fuzzer.target.Syscalls { + fmt.Printf(" #%v: %v [%v]: enabled=%v\n", i, meta.Name, meta.ID, fuzzer.choiceTable.Enabled(meta.ID)) + } + panic("disabled syscall") + } + } +} + func (fuzzer *FuzzerSnapshot) chooseProgram(r *rand.Rand) *prog.Prog { randVal := r.Int63n(fuzzer.sumPrios + 1) idx := sort.Search(len(fuzzer.corpusPrios), func(i int) bool { diff --git a/syz-fuzzer/proc.go b/syz-fuzzer/proc.go index 84f214cec..1b05c7f9b 100644 --- a/syz-fuzzer/proc.go +++ b/syz-fuzzer/proc.go @@ -280,7 +280,7 @@ func (proc *Proc) executeRaw(opts *ipc.ExecOpts, p *prog.Prog, stat Stat) *ipc.P if opts.Flags&ipc.FlagDedupCover == 0 { log.Fatalf("dedup cover is not enabled") } - proc.checkDisabledCalls(p) + proc.fuzzer.checkDisabledCalls(p) // Limit concurrency window and do leak checking once in a while. ticket := proc.fuzzer.gate.Enter() @@ -310,25 +310,6 @@ func (proc *Proc) executeRaw(opts *ipc.ExecOpts, p *prog.Prog, stat Stat) *ipc.P } } -func (proc *Proc) checkDisabledCalls(p *prog.Prog) { - for _, call := range p.Calls { - if !proc.fuzzer.choiceTable.Enabled(call.Meta.ID) { - fmt.Printf("executing disabled syscall %v [%v]\n", call.Meta.Name, call.Meta.ID) - sandbox := ipc.FlagsToSandbox(proc.fuzzer.config.Flags) - fmt.Printf("check result for sandbox=%v:\n", sandbox) - for _, id := range proc.fuzzer.checkResult.EnabledCalls[sandbox] { - meta := proc.fuzzer.target.Syscalls[id] - fmt.Printf(" %v [%v]\n", meta.Name, meta.ID) - } - fmt.Printf("choice table:\n") - for i, meta := range proc.fuzzer.target.Syscalls { - fmt.Printf(" #%v: %v [%v]: enabled=%v\n", i, meta.Name, meta.ID, proc.fuzzer.choiceTable.Enabled(meta.ID)) - } - panic("disabled syscall") - } - } -} - func (proc *Proc) logProgram(opts *ipc.ExecOpts, p *prog.Prog) { if proc.fuzzer.outputType == OutputNone { return -- cgit mrf-deployment