aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--prog/prio.go6
-rw-r--r--prog/rand.go2
-rw-r--r--syz-fuzzer/proc.go5
-rw-r--r--syz-manager/manager.go63
-rw-r--r--syz-manager/rpc.go49
5 files changed, 67 insertions, 58 deletions
diff --git a/prog/prio.go b/prog/prio.go
index ccdab7bda..3a3f31b63 100644
--- a/prog/prio.go
+++ b/prog/prio.go
@@ -254,7 +254,7 @@ func (target *Target) BuildChoiceTable(corpus []*Prog, enabled map[*Syscall]bool
return &ChoiceTable{target, run, enabledCalls}
}
-func (ct *ChoiceTable) enabled(call int) bool {
+func (ct *ChoiceTable) Enabled(call int) bool {
return ct.runs[call] != nil
}
@@ -262,13 +262,13 @@ func (ct *ChoiceTable) choose(r *rand.Rand, bias int) int {
if bias < 0 {
bias = ct.calls[r.Intn(len(ct.calls))].ID
}
- if !ct.enabled(bias) {
+ if !ct.Enabled(bias) {
panic("bias to disabled syscall")
}
run := ct.runs[bias]
x := r.Intn(run[len(run)-1]) + 1
res := sort.SearchInts(run, x)
- if !ct.enabled(res) {
+ if !ct.Enabled(res) {
panic("selected disabled syscall")
}
return res
diff --git a/prog/rand.go b/prog/rand.go
index 019745161..b3d10cf42 100644
--- a/prog/rand.go
+++ b/prog/rand.go
@@ -379,7 +379,7 @@ func (r *randGen) createResource(s *state, res *ResourceType, dir Dir) (arg Arg,
// TODO: reduce priority of less specialized ctors.
var metas []*Syscall
for _, meta := range metas0 {
- if s.ct.enabled(meta.ID) {
+ if s.ct.Enabled(meta.ID) {
metas = append(metas, meta)
}
}
diff --git a/syz-fuzzer/proc.go b/syz-fuzzer/proc.go
index d815a58b9..3c39879cc 100644
--- a/syz-fuzzer/proc.go
+++ b/syz-fuzzer/proc.go
@@ -277,6 +277,11 @@ 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")
}
+ for _, call := range p.Calls {
+ if !proc.fuzzer.choiceTable.Enabled(call.Meta.ID) {
+ panic(fmt.Sprintf("executing disabled syscall %v", call.Meta.Name))
+ }
+ }
// Limit concurrency window and do leak checking once in a while.
ticket := proc.fuzzer.gate.Enter()
diff --git a/syz-manager/manager.go b/syz-manager/manager.go
index 2a0b7dd48..f8e97f1ea 100644
--- a/syz-manager/manager.go
+++ b/syz-manager/manager.go
@@ -65,9 +65,10 @@ type Manager struct {
dash *dashapi.Dashboard
- mu sync.Mutex
- phase int
- enabledSyscalls []int
+ mu sync.Mutex
+ phase int
+ configEnabledSyscalls []int
+ targetEnabledSyscalls map[*prog.Syscall]bool
candidates []rpctype.RPCCandidate // untriaged inputs from corpus and hub
disabledHashes map[string]struct{}
@@ -157,27 +158,27 @@ func RunManager(cfg *mgrconfig.Config, target *prog.Target, sysTarget *targets.T
}
mgr := &Manager{
- cfg: cfg,
- vmPool: vmPool,
- target: target,
- sysTarget: sysTarget,
- reporter: reporter,
- crashdir: crashdir,
- startTime: time.Now(),
- stats: &Stats{haveHub: cfg.HubClient != ""},
- crashTypes: make(map[string]bool),
- enabledSyscalls: syscalls,
- corpus: make(map[string]rpctype.RPCInput),
- disabledHashes: make(map[string]struct{}),
- memoryLeakFrames: make(map[string]bool),
- dataRaceFrames: make(map[string]bool),
- fresh: true,
- vmStop: make(chan bool),
- hubReproQueue: make(chan *Crash, 10),
- needMoreRepros: make(chan chan bool),
- reproRequest: make(chan chan map[string]bool),
- usedFiles: make(map[string]time.Time),
- saturatedCalls: make(map[string]bool),
+ cfg: cfg,
+ vmPool: vmPool,
+ target: target,
+ sysTarget: sysTarget,
+ reporter: reporter,
+ crashdir: crashdir,
+ startTime: time.Now(),
+ stats: &Stats{haveHub: cfg.HubClient != ""},
+ crashTypes: make(map[string]bool),
+ configEnabledSyscalls: syscalls,
+ corpus: make(map[string]rpctype.RPCInput),
+ disabledHashes: make(map[string]struct{}),
+ memoryLeakFrames: make(map[string]bool),
+ dataRaceFrames: make(map[string]bool),
+ fresh: true,
+ vmStop: make(chan bool),
+ hubReproQueue: make(chan *Crash, 10),
+ needMoreRepros: make(chan chan bool),
+ reproRequest: make(chan chan map[string]bool),
+ usedFiles: make(map[string]time.Time),
+ saturatedCalls: make(map[string]bool),
}
log.Logf(0, "loading corpus...")
@@ -469,10 +470,6 @@ func (mgr *Manager) loadCorpus() {
fallthrough
case currentDBVersion:
}
- syscalls := make(map[int]bool)
- for _, id := range mgr.checkResult.EnabledCalls[mgr.cfg.Sandbox] {
- syscalls[id] = true
- }
broken, tooLong := 0, 0
for key, rec := range mgr.corpusDB.Records {
p, err := mgr.target.Deserialize(rec.Val, prog.NonStrict)
@@ -489,7 +486,7 @@ func (mgr *Manager) loadCorpus() {
disabled := false
for _, c := range p.Calls {
- if !syscalls[c.Meta.ID] {
+ if !mgr.targetEnabledSyscalls[c.Meta] {
disabled = true
break
}
@@ -1008,7 +1005,7 @@ func (mgr *Manager) fuzzerConnect() ([]rpctype.RPCInput, BugFrames) {
return corpus, BugFrames{memoryLeaks: memoryLeakFrames, dataRaces: dataRaceFrames}
}
-func (mgr *Manager) machineChecked(a *rpctype.CheckArgs) {
+func (mgr *Manager) machineChecked(a *rpctype.CheckArgs, enabledSyscalls map[*prog.Syscall]bool) {
mgr.mu.Lock()
defer mgr.mu.Unlock()
if len(mgr.cfg.EnabledSyscalls) != 0 && len(a.DisabledCalls[mgr.cfg.Sandbox]) != 0 {
@@ -1016,7 +1013,7 @@ func (mgr *Manager) machineChecked(a *rpctype.CheckArgs) {
for _, dc := range a.DisabledCalls[mgr.cfg.Sandbox] {
disabled[mgr.target.Syscalls[dc.ID].Name] = dc.Reason
}
- for _, id := range mgr.enabledSyscalls {
+ for _, id := range mgr.configEnabledSyscalls {
name := mgr.target.Syscalls[id].Name
if reason := disabled[name]; reason != "" {
log.Logf(0, "disabling %v: %v", name, reason)
@@ -1027,12 +1024,12 @@ func (mgr *Manager) machineChecked(a *rpctype.CheckArgs) {
log.Fatalf("machine check: %v", a.Error)
}
log.Logf(0, "machine check:")
- log.Logf(0, "%-24v: %v/%v", "syscalls",
- len(a.EnabledCalls[mgr.cfg.Sandbox]), len(mgr.target.Syscalls))
+ log.Logf(0, "%-24v: %v/%v", "syscalls", len(enabledSyscalls), len(mgr.target.Syscalls))
for _, feat := range a.Features.Supported() {
log.Logf(0, "%-24v: %v", feat.Name, feat.Reason)
}
mgr.checkResult = a
+ mgr.targetEnabledSyscalls = enabledSyscalls
mgr.loadCorpus()
mgr.firstConnect = time.Now()
}
diff --git a/syz-manager/rpc.go b/syz-manager/rpc.go
index 91e31dbd9..d734b8da9 100644
--- a/syz-manager/rpc.go
+++ b/syz-manager/rpc.go
@@ -18,12 +18,13 @@ import (
)
type RPCServer struct {
- mgr RPCManagerView
- target *prog.Target
- enabledSyscalls []int
- stats *Stats
- sandbox string
- batchSize int
+ mgr RPCManagerView
+ target *prog.Target
+ configEnabledSyscalls []int
+ targetEnabledSyscalls map[*prog.Syscall]bool
+ stats *Stats
+ sandbox string
+ batchSize int
mu sync.Mutex
fuzzers map[string]*Fuzzer
@@ -50,7 +51,7 @@ type BugFrames struct {
// RPCManagerView restricts interface between RPCServer and Manager.
type RPCManagerView interface {
fuzzerConnect() ([]rpctype.RPCInput, BugFrames)
- machineChecked(result *rpctype.CheckArgs)
+ machineChecked(result *rpctype.CheckArgs, enabledSyscalls map[*prog.Syscall]bool)
newInput(inp rpctype.RPCInput, sign signal.Signal) bool
candidateBatch(size int) []rpctype.RPCCandidate
rotateCorpus() bool
@@ -58,13 +59,13 @@ type RPCManagerView interface {
func startRPCServer(mgr *Manager) (int, error) {
serv := &RPCServer{
- mgr: mgr,
- target: mgr.target,
- enabledSyscalls: mgr.enabledSyscalls,
- stats: mgr.stats,
- sandbox: mgr.cfg.Sandbox,
- fuzzers: make(map[string]*Fuzzer),
- rnd: rand.New(rand.NewSource(time.Now().UnixNano())),
+ mgr: mgr,
+ target: mgr.target,
+ configEnabledSyscalls: mgr.configEnabledSyscalls,
+ stats: mgr.stats,
+ sandbox: mgr.cfg.Sandbox,
+ fuzzers: make(map[string]*Fuzzer),
+ rnd: rand.New(rand.NewSource(time.Now().UnixNano())),
}
serv.batchSize = 5
if serv.batchSize < mgr.cfg.Procs {
@@ -95,7 +96,7 @@ func (serv *RPCServer) Connect(a *rpctype.ConnectArgs, r *rpctype.ConnectRes) er
serv.fuzzers[a.Name] = f
r.MemoryLeakFrames = bugFrames.memoryLeaks
r.DataRaceFrames = bugFrames.dataRaces
- r.EnabledCalls = serv.enabledSyscalls
+ r.EnabledCalls = serv.configEnabledSyscalls
r.GitRevision = prog.GitRevision
r.TargetRevision = serv.target.Revision
// TODO: temporary disabled b/c we suspect this negatively affects fuzzing.
@@ -195,14 +196,14 @@ func (serv *RPCServer) Check(a *rpctype.CheckArgs, r *int) error {
if serv.checkResult != nil {
return nil
}
- serv.mgr.machineChecked(a)
- a.DisabledCalls = nil
- serv.checkResult = a
- calls := make(map[*prog.Syscall]bool)
+ serv.targetEnabledSyscalls = make(map[*prog.Syscall]bool)
for _, call := range a.EnabledCalls[serv.sandbox] {
- calls[serv.target.Syscalls[call]] = true
+ serv.targetEnabledSyscalls[serv.target.Syscalls[call]] = true
}
- serv.rotator = prog.MakeRotator(serv.target, calls, serv.rnd)
+ serv.mgr.machineChecked(a, serv.targetEnabledSyscalls)
+ a.DisabledCalls = nil
+ serv.checkResult = a
+ serv.rotator = prog.MakeRotator(serv.target, serv.targetEnabledSyscalls, serv.rnd)
return nil
}
@@ -220,6 +221,12 @@ func (serv *RPCServer) NewInput(a *rpctype.NewInputArgs, r *int) error {
log.Logf(0, "rejecting too long program from fuzzer: %v calls\n%s", len(p.Calls), a.RPCInput.Prog)
return nil
}
+ for _, call := range p.Calls {
+ if !serv.targetEnabledSyscalls[call.Meta] {
+ log.Logf(0, "rejecting program with disabled call %v:\n%s", call.Meta.Name, a.RPCInput.Prog)
+ return nil
+ }
+ }
serv.mu.Lock()
defer serv.mu.Unlock()