github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/syz-runner/runner.go (about) 1 // Copyright 2021 syzkaller project authors. All rights reserved. 2 // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. 3 package main 4 5 import ( 6 "flag" 7 "log" 8 "runtime" 9 10 "github.com/google/syzkaller/pkg/ipc" 11 "github.com/google/syzkaller/pkg/ipc/ipcconfig" 12 "github.com/google/syzkaller/pkg/rpctype" 13 "github.com/google/syzkaller/prog" 14 ) 15 16 // Runner is responsible of running programs sent by the host via RPC and 17 // reporting the execution results back to the host. 18 type Runner struct { 19 vrf *rpctype.RPCClient 20 target *prog.Target 21 opts *ipc.ExecOpts 22 config *ipc.Config 23 pool, vm int 24 newEnv bool 25 } 26 27 func main() { 28 flagPool := flag.Int("pool", 0, "index of pool it corresponds to") 29 flagVM := flag.Int("vm", 0, "index of VM that started the Runner") 30 flagAddr := flag.String("addr", "", "verifier rpc address") 31 flagOS := flag.String("os", runtime.GOOS, "target OS") 32 flagArch := flag.String("arch", runtime.GOARCH, "target arch") 33 flagEnv := flag.Bool("new-env", true, "create a new environment for each program") 34 flag.Parse() 35 36 target, err := prog.GetTarget(*flagOS, *flagArch) 37 if err != nil { 38 log.Fatalf("failed to configure target: %v", err) 39 } 40 41 config, opts, err := ipcconfig.Default(target) 42 if err != nil { 43 log.Fatalf("failed to create default ipc config: %v", err) 44 } 45 46 vrf, err := rpctype.NewRPCClient(*flagAddr) 47 if err != nil { 48 log.Fatalf("failed to connect to verifier : %v", err) 49 } 50 51 rn := &Runner{ 52 vrf: vrf, 53 target: target, 54 opts: opts, 55 config: config, 56 pool: *flagPool, 57 vm: *flagVM, 58 newEnv: *flagEnv, 59 } 60 61 a := &rpctype.RunnerConnectArgs{ 62 Pool: rn.pool, 63 VM: rn.vm, 64 } 65 r := &rpctype.RunnerConnectRes{} 66 if err := vrf.Call("Verifier.Connect", a, r); err != nil { 67 log.Fatalf("failed to connect to verifier: %v", err) 68 } 69 70 enabled := make(map[*prog.Syscall]bool) 71 for _, c := range target.Syscalls { 72 enabled[c] = true 73 } 74 if r.CheckUnsupportedCalls { 75 a := &rpctype.UpdateUnsupportedArgs{Pool: rn.pool, UnsupportedCalls: nil} 76 if err := vrf.Call("Verifier.UpdateUnsupported", a, nil); err != nil { 77 log.Fatalf("failed to send unsupported system calls: %v", err) 78 } 79 } 80 81 res := &rpctype.NextExchangeRes{} 82 if err := rn.vrf.Call("Verifier.NextExchange", &rpctype.NextExchangeArgs{Pool: rn.pool, VM: rn.vm}, res); err != nil { 83 log.Fatalf("failed to get initial program: %v", err) 84 } 85 86 rn.Run(res.Prog, res.ID) 87 } 88 89 // Run is responsible for requesting new programs from the verifier, executing them and then sending back the Result. 90 // TODO: Implement functionality to execute several programs at once and send back a slice of results. 91 func (rn *Runner) Run(firstProg []byte, taskID int64) { 92 p, id := firstProg, taskID 93 94 env, err := ipc.MakeEnv(rn.config, 0) 95 if err != nil { 96 log.Fatalf("failed to create initial execution environment: %v", err) 97 } 98 99 for { 100 prog, err := rn.target.Deserialize(p, prog.NonStrict) 101 if err != nil { 102 log.Fatalf("failed to deserialise new program: %v", err) 103 } 104 105 log.Printf("executing program") // watchdog for monitor 106 _, info, hanged, err := env.Exec(rn.opts, prog) 107 if err != nil { 108 log.Fatalf("failed to execute the program: %v", err) 109 } 110 111 a := &rpctype.NextExchangeArgs{ 112 Pool: rn.pool, 113 VM: rn.vm, 114 Hanged: hanged, 115 Info: *info, 116 ExecTaskID: id, 117 } 118 119 r := &rpctype.NextExchangeRes{} 120 if err := rn.vrf.Call("Verifier.NextExchange", a, r); err != nil { 121 log.Fatalf("failed to make exchange with verifier: %v", err) 122 } 123 p, id = r.Prog, r.ID 124 125 if !rn.newEnv { 126 continue 127 } 128 129 err = env.Close() 130 if err != nil { 131 log.Fatalf("failed to close the execution environment: %v", err) 132 } 133 134 env, err = ipc.MakeEnv(rn.config, 0) 135 if err != nil { 136 log.Fatalf("failed to create new execution environment: %v", err) 137 } 138 } 139 }