aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile22
-rw-r--r--master/html.go95
-rw-r--r--master/master.go170
-rw-r--r--syz-fuzzer/fuzzer.go (renamed from fuzzer/fuzzer.go)0
-rw-r--r--syz-manager/cover.go (renamed from manager/cover.go)0
-rw-r--r--syz-manager/example.cfg (renamed from manager/example.cfg)5
-rw-r--r--syz-manager/html.go (renamed from manager/html.go)55
-rw-r--r--syz-manager/main.go (renamed from manager/main.go)8
-rw-r--r--syz-manager/manager.go (renamed from manager/manager.go)147
-rw-r--r--syz-manager/persistent.go (renamed from master/persistent.go)0
-rw-r--r--tools/syz-execprog/execprog.go (renamed from tools/execprog/execprog.go)0
-rw-r--r--tools/syz-mutate/mutate.go (renamed from tools/mutate/mutate.go)0
-rw-r--r--tools/syz-prog2c/prog2c.go (renamed from tools/prog2c/prog2c.go)0
-rw-r--r--tools/syz-stress/stress.go (renamed from tools/stress/stress.go)0
-rw-r--r--vm/qemu/qemu.go6
15 files changed, 69 insertions, 439 deletions
diff --git a/Makefile b/Makefile
index 0e429e4de..dc4918fff 100644
--- a/Makefile
+++ b/Makefile
@@ -1,24 +1,18 @@
# Copyright 2015 syzkaller project authors. All rights reserved.
# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
-.PHONY: all bin format clean master manager fuzzer executor
+.PHONY: all format clean master manager fuzzer executor
-all: master manager fuzzer executor
+all: manager fuzzer executor
-bin:
- mkdir -p bin
+manager:
+ go build -o ./bin/syz-manager github.com/google/syzkaller/syz-manager
-master: bin
- go build -o ./bin/master github.com/google/syzkaller/master
+fuzzer:
+ go build -o ./bin/syz-fuzzer github.com/google/syzkaller/syz-fuzzer
-manager: bin
- go build -o ./bin/manager github.com/google/syzkaller/manager
-
-fuzzer: bin
- go build -o ./bin/fuzzer github.com/google/syzkaller/fuzzer
-
-executor: bin
- gcc executor/executor.cc -o ./bin/executor -lpthread -static -Wall -O1 -g
+executor:
+ gcc -o ./bin/syz-executor executor/executor.cc -lpthread -static -Wall -O1 -g
format:
go fmt ./...
diff --git a/master/html.go b/master/html.go
deleted file mode 100644
index 40159d156..000000000
--- a/master/html.go
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2015 syzkaller project authors. All rights reserved.
-// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
-
-package main
-
-import (
- "encoding/json"
- "fmt"
- "html/template"
- "io/ioutil"
- "net/http"
-)
-
-func (m *Master) httpInfo(w http.ResponseWriter, r *http.Request) {
- m.mu.Lock()
- defer m.mu.Unlock()
-
- data := &UIData{
- CorpusLen: len(m.corpus.m),
- }
- for _, mgr := range m.managers {
- data.Managers = append(data.Managers, UIManager{
- Name: mgr.name,
- Http: mgr.http,
- })
- }
- if err := htmlTemplate.Execute(w, data); err != nil {
- http.Error(w, fmt.Sprintf("failed to execute template: %v", err), http.StatusInternalServerError)
- }
-}
-
-func (m *Master) httpMinimize(w http.ResponseWriter, r *http.Request) {
- corpus := make(map[string]bool)
- for _, mgr := range m.managers {
- resp, err := http.Get("http://" + mgr.http + "/current_corpus")
- if err != nil {
- http.Error(w, fmt.Sprintf("failed to query corpus from %v: %v", mgr.name, err), http.StatusInternalServerError)
- return
- }
- defer resp.Body.Close()
- data, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- http.Error(w, fmt.Sprintf("failed to query corpus from %v: %v", mgr.name, err), http.StatusInternalServerError)
- return
- }
- var hashes []string
- err = json.Unmarshal(data, &hashes)
- if err != nil || len(hashes) == 0 {
- http.Error(w, fmt.Sprintf("failed to parse corpus from %v: %v", mgr.name, err), http.StatusInternalServerError)
- return
- }
- for _, hash := range hashes {
- corpus[hash] = true
- }
- }
-
- m.mu.Lock()
- defer m.mu.Unlock()
-
- orig := len(m.corpus.m)
- m.corpus.minimize(corpus)
- fmt.Printf("minimized: %v -> %v -> %v\n", orig, len(corpus), len(m.corpus.m))
- for _, mgr := range m.managers {
- mgr.input = 0
- }
-}
-
-type UIData struct {
- CorpusLen int
- Managers []UIManager
-}
-
-type UIManager struct {
- Name string
- Http string
-}
-
-var htmlTemplate = template.Must(template.New("").Parse(`
-<!doctype html>
-<html>
-<head>
- <title>syzkaller master</title>
-</head>
-<body>
-Corpus: {{.CorpusLen}} <br>
-{{if .Managers}}
- Managers:<br>
- {{range $mgr := $.Managers}}
- <a href='http://{{$mgr.Http}}'>{{$mgr.Name}}</a><br>
- {{end}}
-{{else}}
- No managers connected<br>
-{{end}}
-</body></html>
-`))
diff --git a/master/master.go b/master/master.go
deleted file mode 100644
index c1a427732..000000000
--- a/master/master.go
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright 2015 syzkaller project authors. All rights reserved.
-// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
-
-package main
-
-import (
- "flag"
- "fmt"
- "log"
- "net"
- "net/http"
- "net/rpc"
- "path/filepath"
- "sync"
- "time"
-
- "github.com/google/syzkaller/prog"
- . "github.com/google/syzkaller/rpctype"
-)
-
-var (
- flagWorkdir = flag.String("workdir", "", "dir with persistent artifacts")
- flagAddr = flag.String("addr", "", "RPC listen address to connect managers")
- flagHTTP = flag.String("http", "", "HTTP server listen address")
- flagV = flag.Int("v", 0, "verbosity")
-)
-
-// Master manages persistent fuzzer state (input corpus and crashers).
-type Master struct {
- mu sync.Mutex
- managers map[string]*Manager
- corpus *PersistentSet
- crashers *PersistentSet
- startTime time.Time
- lastInput time.Time
-}
-
-type Manager struct {
- name string
- http string
- input int
-}
-
-func main() {
- flag.Parse()
- if *flagWorkdir == "" {
- fatalf("-workdir is not set")
- }
- if *flagAddr == "" {
- fatalf("-addr is not set")
- }
- if *flagHTTP == "" {
- fatalf("-http is not set")
- }
- ln, err := net.Listen("tcp", *flagAddr)
- if err != nil {
- fatalf("failed to listen: %v", err)
- }
-
- m := &Master{}
- m.managers = make(map[string]*Manager)
- m.startTime = time.Now()
- m.lastInput = time.Now()
- logf(0, "loading corpus...")
- m.corpus = newPersistentSet(filepath.Join(*flagWorkdir, "corpus"), func(data []byte) bool {
- if _, err := prog.Deserialize(data); err != nil {
- logf(0, "deleting broken program: %v\n%s", err, data)
- return false
- }
- return true
- })
- m.crashers = newPersistentSet(filepath.Join(*flagWorkdir, "crashers"), nil)
-
- http.HandleFunc("/", m.httpInfo)
- http.HandleFunc("/minimize", m.httpMinimize)
- go func() {
- logf(0, "serving http on http://%v", *flagHTTP)
- panic(http.ListenAndServe(*flagHTTP, nil))
- }()
-
- logf(0, "serving rpc on tcp://%v", *flagAddr)
- s := rpc.NewServer()
- s.Register(m)
- go s.Accept(ln)
-
- m.loop()
-}
-
-func (m *Master) loop() {
- for range time.NewTicker(1 * time.Second).C {
- }
-}
-
-// Connect attaches new manager to master.
-func (m *Master) Connect(a *MasterConnectArgs, r *MasterConnectRes) error {
- logf(1, "connect from %v (http://%v)", a.Name, a.Http)
- m.mu.Lock()
- defer m.mu.Unlock()
-
- mgr := &Manager{
- name: a.Name,
- http: a.Http,
- }
- m.managers[a.Name] = mgr
- r.Http = *flagHTTP
- return nil
-}
-
-// NewInput saves new interesting input on master.
-func (m *Master) NewInput(a *NewMasterInputArgs, r *int) error {
- p, err := prog.Deserialize(a.Prog)
- if err != nil {
- logf(0, "bogus new input from %v: %v\n%s\n", a.Name, err, a.Prog)
- return fmt.Errorf("the program is bogus: %v", err)
- }
- m.mu.Lock()
- defer m.mu.Unlock()
-
- if !m.corpus.add(a.Prog) {
- return nil
- }
- m.lastInput = time.Now()
- logf(1, "new input from %v: %s", a.Name, p)
- return nil
-}
-
-type NewCrasherArgs struct {
- Name string
- Text []byte
- Suppression []byte
- Prog []byte
-}
-
-// NewCrasher saves new crasher input on master.
-func (m *Master) NewCrasher(a *NewCrasherArgs, r *int) error {
- logf(0, "new crasher from %v", a.Name)
- m.mu.Lock()
- defer m.mu.Unlock()
-
- if !m.crashers.add(a.Text) {
- return nil // Already have this.
- }
- return nil
-}
-
-func (m *Master) PollInputs(a *MasterPollArgs, r *MasterPollRes) error {
- logf(2, "poll from %v", a.Name)
- m.mu.Lock()
- defer m.mu.Unlock()
-
- mgr := m.managers[a.Name]
- if mgr == nil {
- return fmt.Errorf("manager is not connected")
- }
- for i := 0; i < 100 && mgr.input < len(m.corpus.a); i++ {
- r.Inputs = append(r.Inputs, m.corpus.a[mgr.input])
- mgr.input++
- }
- return nil
-}
-
-func logf(v int, msg string, args ...interface{}) {
- if *flagV >= v {
- log.Printf(msg, args...)
- }
-}
-
-func fatalf(msg string, args ...interface{}) {
- log.Fatalf(msg, args...)
-}
diff --git a/fuzzer/fuzzer.go b/syz-fuzzer/fuzzer.go
index 34d99499f..34d99499f 100644
--- a/fuzzer/fuzzer.go
+++ b/syz-fuzzer/fuzzer.go
diff --git a/manager/cover.go b/syz-manager/cover.go
index 190fb6038..190fb6038 100644
--- a/manager/cover.go
+++ b/syz-manager/cover.go
diff --git a/manager/example.cfg b/syz-manager/example.cfg
index 216e09eeb..a9095ef18 100644
--- a/manager/example.cfg
+++ b/syz-manager/example.cfg
@@ -1,7 +1,5 @@
{
- "name": "my-qemu-asan",
"http": "myhost.com:56741",
- "master": "myhost.com:48342",
"workdir": "/syzkaller/manager/workdir",
"vmlinux": "/linux/vmlinux",
"type": "qemu",
@@ -21,5 +19,8 @@
"keyctl",
"add_key",
"request_key"
+ ],
+ "suppressions": [
+ "some known bug"
]
}
diff --git a/manager/html.go b/syz-manager/html.go
index 6123160d9..0d7e87687 100644
--- a/manager/html.go
+++ b/syz-manager/html.go
@@ -4,8 +4,6 @@
package main
import (
- "encoding/hex"
- "encoding/json"
"fmt"
"html/template"
"net/http"
@@ -23,11 +21,8 @@ func (mgr *Manager) initHttp() {
http.HandleFunc("/corpus", mgr.httpCorpus)
http.HandleFunc("/cover", mgr.httpCover)
http.HandleFunc("/prio", mgr.httpPrio)
- http.HandleFunc("/current_corpus", mgr.httpCurrentCorpus)
- go func() {
- logf(0, "serving http on http://%v", mgr.cfg.Http)
- panic(http.ListenAndServe(mgr.cfg.Http, nil))
- }()
+ logf(0, "serving http on http://%v", mgr.cfg.Http)
+ go http.ListenAndServe(mgr.cfg.Http, nil)
}
func (mgr *Manager) httpInfo(w http.ResponseWriter, r *http.Request) {
@@ -50,12 +45,9 @@ func (mgr *Manager) httpInfo(w http.ResponseWriter, r *http.Request) {
uptime := time.Since(mgr.startTime)
data := &UIData{
- Name: mgr.cfg.Name,
- MasterHttp: mgr.masterHttp,
- MasterCorpusSize: len(mgr.masterCorpus),
- CorpusSize: len(mgr.corpus),
- TriageQueue: len(mgr.candidates),
- Uptime: fmt.Sprintf("%v", uptime),
+ CorpusSize: len(mgr.corpus),
+ TriageQueue: len(mgr.candidates),
+ Uptime: fmt.Sprintf("%v", uptime),
}
secs := uint64(uptime) / 1e9
@@ -164,34 +156,13 @@ func (mgr *Manager) httpPrio(w http.ResponseWriter, r *http.Request) {
}
}
-func (mgr *Manager) httpCurrentCorpus(w http.ResponseWriter, r *http.Request) {
- mgr.mu.Lock()
- defer mgr.mu.Unlock()
-
- mgr.minimizeCorpus()
- var hashes []string
- for _, inp := range mgr.corpus {
- hash := hash(inp.Prog)
- hashes = append(hashes, hex.EncodeToString(hash[:]))
- }
- data, err := json.Marshal(&hashes)
- if err != nil {
- http.Error(w, fmt.Sprintf("failed to marshal corpus: %v", err), http.StatusInternalServerError)
- return
- }
- w.Write(data)
-}
-
type UIData struct {
- Name string
- MasterHttp string
- MasterCorpusSize int
- CorpusSize int
- TriageQueue int
- CoverSize int
- Uptime string
- Stats []UIStat
- Calls []UICallType
+ CorpusSize int
+ TriageQueue int
+ CoverSize int
+ Uptime string
+ Stats []UIStat
+ Calls []UICallType
}
type UIStat struct {
@@ -235,12 +206,10 @@ var htmlTemplate = template.Must(template.New("").Parse(`
<!doctype html>
<html>
<head>
- <title>syzkaller {{.Name}}</title>
+ <title>syzkaller</title>
</head>
<body>
-Manager: {{.Name}} <a href='http://{{.MasterHttp}}'>[master]</a> <br>
Uptime: {{.Uptime}}<br>
-Master corpus: {{.MasterCorpusSize}} <br>
Corpus: {{.CorpusSize}}<br>
Triage queue len: {{.TriageQueue}}<br>
<a href='/cover'>Cover: {{.CoverSize}}</a> <br>
diff --git a/manager/main.go b/syz-manager/main.go
index 9a3523cb8..acbba0967 100644
--- a/manager/main.go
+++ b/syz-manager/main.go
@@ -26,9 +26,7 @@ var (
)
type Config struct {
- Name string
Http string
- Master string
Workdir string
Vmlinux string
Type string
@@ -110,15 +108,9 @@ func parseConfig() (*Config, map[int]bool) {
if err := json.Unmarshal(data, cfg); err != nil {
fatalf("failed to parse config file: %v", err)
}
- if cfg.Name == "" {
- fatalf("config param name is empty")
- }
if cfg.Http == "" {
fatalf("config param http is empty")
}
- if cfg.Master == "" {
- fatalf("config param master is empty")
- }
if cfg.Workdir == "" {
fatalf("config param workdir is empty")
}
diff --git a/manager/manager.go b/syz-manager/manager.go
index ab40bbe0d..44510d7e1 100644
--- a/manager/manager.go
+++ b/syz-manager/manager.go
@@ -4,10 +4,10 @@
package main
import (
- "crypto/sha1"
"fmt"
"net"
"net/rpc"
+ "path/filepath"
"sync"
"time"
@@ -18,26 +18,17 @@ import (
"github.com/google/syzkaller/vm"
)
-type Sig [sha1.Size]byte
-
-func hash(data []byte) Sig {
- return Sig(sha1.Sum(data))
-}
-
type Manager struct {
- cfg *Config
- master *rpc.Client
- masterHttp string
- instances []vm.Instance
- startTime time.Time
- stats map[string]uint64
-
- mu sync.Mutex
- masterCorpus [][]byte // mirror of master corpus
- masterHashes map[Sig]struct{} // hashes of master corpus
- candidates [][]byte // new untriaged inputs from master
- syscalls map[int]bool
+ cfg *Config
+ persistentCorpus *PersistentSet
+ instances []vm.Instance
+ startTime time.Time
+ stats map[string]uint64
+ mu sync.Mutex
+ syscalls map[int]bool
+
+ candidates [][]byte // untriaged inputs
corpus []RpcInput
corpusCover []cover.Cover
prios [][]float32
@@ -51,30 +42,28 @@ type Fuzzer struct {
}
func RunManager(cfg *Config, syscalls map[int]bool, instances []vm.Instance) {
- // Connect to master.
- master, err := rpc.Dial("tcp", cfg.Master)
- if err != nil {
- fatalf("failed to dial mastger: %v", err)
- }
- a := &MasterConnectArgs{cfg.Name, cfg.Http}
- r := &MasterConnectRes{}
- if err := master.Call("Master.Connect", a, r); err != nil {
- fatalf("failed to connect to master: %v", err)
- }
- logf(0, "connected to master at %v", cfg.Master)
-
mgr := &Manager{
- cfg: cfg,
- master: master,
- masterHttp: r.Http,
- startTime: time.Now(),
- stats: make(map[string]uint64),
- instances: instances,
- masterHashes: make(map[Sig]struct{}),
- syscalls: syscalls,
- corpusCover: make([]cover.Cover, sys.CallCount),
- fuzzers: make(map[string]*Fuzzer),
+ cfg: cfg,
+ startTime: time.Now(),
+ stats: make(map[string]uint64),
+ instances: instances,
+ syscalls: syscalls,
+ corpusCover: make([]cover.Cover, sys.CallCount),
+ fuzzers: make(map[string]*Fuzzer),
+ }
+
+ logf(0, "loading corpus...")
+ mgr.persistentCorpus = newPersistentSet(filepath.Join(cfg.Workdir, "corpus"), func(data []byte) bool {
+ if _, err := prog.Deserialize(data); err != nil {
+ logf(0, "deleting broken program: %v\n%s", err, data)
+ return false
+ }
+ return true
+ })
+ for _, prog := range mgr.persistentCorpus.a {
+ mgr.candidates = append(mgr.candidates, prog)
}
+ logf(0, "loaded %v programs", len(mgr.persistentCorpus.m))
// Create HTTP server.
mgr.initHttp()
@@ -85,64 +74,15 @@ func RunManager(cfg *Config, syscalls map[int]bool, instances []vm.Instance) {
if err != nil {
fatalf("failed to listen on port %v: %v", cfg.Port, err)
}
+ logf(0, "serving rpc on tcp://%v", rpcAddr)
s := rpc.NewServer()
s.Register(mgr)
go s.Accept(ln)
- logf(0, "serving rpc on tcp://%v", rpcAddr)
-
- mgr.run()
-}
-func (mgr *Manager) run() {
- mgr.pollMaster()
for _, inst := range mgr.instances {
go inst.Run()
}
- pollTicker := time.NewTicker(10 * time.Second).C
- for {
- select {
- case <-pollTicker:
- mgr.mu.Lock()
- mgr.pollMaster()
- mgr.mu.Unlock()
- }
- }
-}
-
-func (mgr *Manager) pollMaster() {
- for {
- a := &MasterPollArgs{mgr.cfg.Name}
- r := &MasterPollRes{}
- if err := mgr.master.Call("Master.PollInputs", a, r); err != nil {
- fatalf("failed to poll master: %v", err)
- }
- logf(3, "polling master, got %v inputs", len(r.Inputs))
- if len(r.Inputs) == 0 {
- break
- }
- nextProg:
- for _, prg := range r.Inputs {
- p, err := prog.Deserialize(prg)
- if err != nil {
- logf(0, "failed to deserialize master program: %v", err)
- continue
- }
- if mgr.syscalls != nil {
- for _, c := range p.Calls {
- if !mgr.syscalls[c.Meta.ID] {
- continue nextProg
- }
- }
- }
- sig := hash(prg)
- if _, ok := mgr.masterHashes[sig]; ok {
- continue
- }
- mgr.masterHashes[sig] = struct{}{}
- mgr.masterCorpus = append(mgr.masterCorpus, prg)
- mgr.candidates = append(mgr.candidates, prg)
- }
- }
+ select {}
}
func (mgr *Manager) minimizeCorpus() {
@@ -178,6 +118,16 @@ func (mgr *Manager) minimizeCorpus() {
corpus = append(corpus, p)
}
mgr.prios = prog.CalculatePriorities(corpus)
+
+ // Don't minimize persistent corpus until fuzzers have triaged all inputs from it.
+ if len(mgr.candidates) == 0 {
+ hashes := make(map[string]bool)
+ for _, inp := range mgr.corpus {
+ h := hash(inp.Prog)
+ hashes[string(h[:])] = true
+ }
+ mgr.persistentCorpus.minimize(hashes)
+ }
}
func (mgr *Manager) Connect(a *ManagerConnectArgs, r *ManagerConnectRes) error {
@@ -208,18 +158,7 @@ func (mgr *Manager) NewInput(a *NewManagerInputArgs, r *int) error {
mgr.corpusCover[call] = cover.Union(mgr.corpusCover[call], a.Cover)
mgr.corpus = append(mgr.corpus, a.RpcInput)
mgr.stats["manager new inputs"]++
-
- sig := hash(a.Prog)
- if _, ok := mgr.masterHashes[sig]; !ok {
- mgr.masterHashes[sig] = struct{}{}
- mgr.masterCorpus = append(mgr.masterCorpus, a.Prog)
-
- a1 := &NewMasterInputArgs{mgr.cfg.Name, a.Prog}
- if err := mgr.master.Call("Master.NewInput", a1, nil); err != nil {
- fatalf("call Master.NewInput failed: %v", err)
- }
- }
-
+ mgr.persistentCorpus.add(a.RpcInput.Prog)
return nil
}
diff --git a/master/persistent.go b/syz-manager/persistent.go
index 12f4bbdc8..12f4bbdc8 100644
--- a/master/persistent.go
+++ b/syz-manager/persistent.go
diff --git a/tools/execprog/execprog.go b/tools/syz-execprog/execprog.go
index dcb2a0b8b..dcb2a0b8b 100644
--- a/tools/execprog/execprog.go
+++ b/tools/syz-execprog/execprog.go
diff --git a/tools/mutate/mutate.go b/tools/syz-mutate/mutate.go
index 353d60390..353d60390 100644
--- a/tools/mutate/mutate.go
+++ b/tools/syz-mutate/mutate.go
diff --git a/tools/prog2c/prog2c.go b/tools/syz-prog2c/prog2c.go
index 9b8e58efa..9b8e58efa 100644
--- a/tools/prog2c/prog2c.go
+++ b/tools/syz-prog2c/prog2c.go
diff --git a/tools/stress/stress.go b/tools/syz-stress/stress.go
index e4f1a506c..e4f1a506c 100644
--- a/tools/stress/stress.go
+++ b/tools/syz-stress/stress.go
diff --git a/vm/qemu/qemu.go b/vm/qemu/qemu.go
index d00e2c050..bb560accb 100644
--- a/vm/qemu/qemu.go
+++ b/vm/qemu/qemu.go
@@ -258,8 +258,8 @@ func (inst *Instance) Run() {
inst.Logf("started vm")
// Copy the binaries into the instance.
- if !inst.CreateSCPCommand(inst.Fuzzer, "/syzkaller_fuzzer").Wait(1*time.Minute) ||
- !inst.CreateSCPCommand(inst.Executor, "/syzkaller_executor").Wait(1*time.Minute) {
+ if !inst.CreateSCPCommand(inst.Fuzzer, "/syz-fuzzer").Wait(1*time.Minute) ||
+ !inst.CreateSCPCommand(inst.Executor, "/syz-executor").Wait(1*time.Minute) {
outputMu.Lock()
output = append(output, "\nfailed to scp binaries into the instance\n"...)
inst.SaveCrasher(output)
@@ -280,7 +280,7 @@ func (inst *Instance) Run() {
if inst.cfg.NoDropPrivs {
dropprivs = "-dropprivs=0"
}
- cmd := inst.CreateSSHCommand(fmt.Sprintf("/syzkaller_fuzzer -name %v -executor /syzkaller_executor -manager %v:%v -procs %v -leak=%v %v %v %v",
+ cmd := inst.CreateSSHCommand(fmt.Sprintf("/syz-fuzzer -name %v -executor /syz-executor -manager %v:%v -procs %v -leak=%v %v %v %v",
inst.name, hostAddr, inst.cfg.ManagerPort, inst.cfg.Procs, inst.cfg.Leak, cover, dropprivs, inst.callsFlag))
deadline := start.Add(time.Hour)