github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/pkg/instance/instance_test.go (about) 1 // Copyright 2018 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 4 package instance 5 6 import ( 7 "flag" 8 "os" 9 "runtime" 10 "strings" 11 "testing" 12 13 "github.com/google/syzkaller/pkg/tool" 14 "github.com/google/syzkaller/sys/targets" 15 ) 16 17 func TestFuzzerCmd(t *testing.T) { 18 // IMPORTANT: if this test fails, do not fix it by changing flags here! 19 // Test how an old version of syz-fuzzer parses flags generated by the current FuzzerCmd. 20 // This actually happens in syz-ci when we test a patch for an old bug and use an old syz-fuzzer/execprog. 21 flags := flag.NewFlagSet("", flag.ContinueOnError) 22 flagName := flags.String("name", "", "unique name for manager") 23 flagArch := flags.String("arch", "", "target arch") 24 flagManager := flags.String("manager", "", "manager rpc address") 25 flagProcs := flags.Int("procs", 1, "number of parallel test processes") 26 flagLeak := flags.Bool("leak", false, "detect memory leaks") 27 flagOutput := flags.String("output", "stdout", "write programs to none/stdout/dmesg/file") 28 flagPprof := flags.String("pprof", "", "address to serve pprof profiles") 29 flagTest := flags.Bool("test", false, "enable image testing mode") // used by syz-ci 30 flagExecutor := flags.String("executor", "./syz-executor", "path to executor binary") 31 flagSignal := flags.Bool("cover", false, "collect feedback signals (coverage)") 32 flagSandbox := flags.String("sandbox", "none", "sandbox for fuzzing (none/setuid/namespace/android)") 33 flagDebug := flags.Bool("debug", false, "debug output from executor") 34 flagV := flags.Int("v", 0, "verbosity") 35 cmdLine := OldFuzzerCmd(os.Args[0], "/myexecutor", "myname", targets.Linux, targets.I386, "localhost:1234", 36 "namespace", 23, 3, true, true, false, 5) 37 args := strings.Split(cmdLine, " ")[1:] 38 if err := flags.Parse(args); err != nil { 39 t.Fatal(err) 40 } 41 if *flagName != "myname" { 42 t.Errorf("bad name: %q, want: %q", *flagName, "myname") 43 } 44 if *flagArch != targets.I386 { 45 t.Errorf("bad arch: %q, want: %q", *flagArch, targets.I386) 46 } 47 if *flagManager != "localhost:1234" { 48 t.Errorf("bad manager: %q, want: %q", *flagManager, "localhost:1234") 49 } 50 if *flagProcs != 3 { 51 t.Errorf("bad procs: %v, want: %v", *flagProcs, 3) 52 } 53 if *flagLeak { 54 t.Errorf("bad leak: %v, want: %v", *flagLeak, false) 55 } 56 if *flagOutput != "stdout" { 57 t.Errorf("bad output: %q, want: %q", *flagOutput, "stdout") 58 } 59 if *flagPprof != "" { 60 t.Errorf("bad pprof: %q, want: %q", *flagPprof, "") 61 } 62 if !*flagTest { 63 t.Errorf("bad test: %v, want: %v", *flagTest, true) 64 } 65 if *flagExecutor != "/myexecutor" { 66 t.Errorf("bad executor: %q, want: %q", *flagExecutor, "/myexecutor") 67 } 68 if *flagSandbox != "namespace" { 69 t.Errorf("bad sandbox: %q, want: %q", *flagSandbox, "namespace") 70 } 71 if !*flagSignal { 72 t.Errorf("bad signal: %v, want: %v", *flagSignal, true) 73 } 74 if *flagDebug { 75 t.Errorf("bad debug: %v, want: %v", *flagDebug, false) 76 } 77 if *flagV != 0 { 78 t.Errorf("bad verbosity: %v, want: %v", *flagV, 0) 79 } 80 } 81 82 func TestExecprogCmd(t *testing.T) { 83 // IMPORTANT: if this test fails, do not fix it by changing flags here! 84 // See comment in TestFuzzerCmd. 85 flags := flag.NewFlagSet("", flag.ContinueOnError) 86 flagOS := flags.String("os", runtime.GOOS, "target os") 87 flagArch := flags.String("arch", "", "target arch") 88 flagRepeat := flags.Int("repeat", 1, "repeat execution that many times (0 for infinite loop)") 89 flagProcs := flags.Int("procs", 1, "number of parallel processes to execute programs") 90 flagFaultCall := flags.Int("fault_call", -1, "inject fault into this call (0-based)") 91 flagFaultNth := flags.Int("fault_nth", 0, "inject fault on n-th operation (0-based)") 92 flagExecutor := flags.String("executor", "./syz-executor", "path to executor binary") 93 flagThreaded := flags.Bool("threaded", true, "use threaded mode in executor") 94 // In the older syzkaller versions `collide` flag defaulted to `true`, but in this 95 // test we can change it to false (new default), because syzkaller always explicitly 96 // sets this flag and never relies on the default value. 97 flagCollide := flags.Bool("collide", false, "collide syscalls to provoke data races") 98 flagSignal := flags.Bool("cover", false, "collect feedback signals (coverage)") 99 flagSandbox := flags.String("sandbox", "none", "sandbox for fuzzing (none/setuid/namespace/android)") 100 flagSlowdown := flags.Int("slowdown", 1, "") 101 cmdLine := ExecprogCmd(os.Args[0], "/myexecutor", targets.FreeBSD, targets.I386, 102 "namespace", 3, true, false, true, 7, 2, 3, true, 10, "myprog") 103 args := strings.Split(cmdLine, " ")[1:] 104 if err := tool.ParseFlags(flags, args); err != nil { 105 t.Fatal(err) 106 } 107 if len(flags.Args()) != 1 || flags.Arg(0) != "myprog" { 108 t.Errorf("bad args: %q, want: %q", flags.Args(), "myprog") 109 } 110 if *flagOS != runtime.GOOS { 111 t.Errorf("bad os: %q, want: %q", *flagOS, runtime.GOOS) 112 } 113 if *flagArch != targets.I386 { 114 t.Errorf("bad arch: %q, want: %q", *flagArch, targets.I386) 115 } 116 if *flagRepeat != 0 { 117 t.Errorf("bad repeat: %v, want: %v", *flagRepeat, 0) 118 } 119 if *flagProcs != 7 { 120 t.Errorf("bad procs: %v, want: %v", *flagProcs, 7) 121 } 122 if *flagFaultCall != 2 { 123 t.Errorf("bad procs: %v, want: %v", *flagFaultCall, 2) 124 } 125 if *flagFaultNth != 3 { 126 t.Errorf("bad procs: %v, want: %v", *flagFaultNth, 3) 127 } 128 if *flagExecutor != "/myexecutor" { 129 t.Errorf("bad executor: %q, want: %q", *flagExecutor, "/myexecutor") 130 } 131 if *flagSandbox != "namespace" { 132 t.Errorf("bad sandbox: %q, want: %q", *flagSandbox, "namespace") 133 } 134 if *flagSignal { 135 t.Errorf("bad signal: %v, want: %v", *flagSignal, false) 136 } 137 if *flagThreaded { 138 t.Errorf("bad threaded: %v, want: %v", *flagThreaded, false) 139 } 140 if !*flagCollide { 141 t.Errorf("bad collide: %v, want: %v", *flagCollide, true) 142 } 143 if *flagSlowdown != 10 { 144 t.Errorf("bad slowdown: %v, want: %v", *flagSlowdown, 10) 145 } 146 } 147 148 func TestRunnerCmd(t *testing.T) { 149 flags := flag.NewFlagSet("", flag.ContinueOnError) 150 flagFwdAddr := flags.String("addr", "", "verifier rpc address") 151 flagOS := flags.String("os", "", "target OS") 152 flagArch := flags.String("arch", "", "target architecture") 153 flagPool := flags.Int("pool", 0, "index of pool that started VM") 154 flagVM := flags.Int("vm", 0, "index of VM that started the Runner") 155 flagThreaded := flags.Bool("threaded", true, "use threaded mode in executor") 156 flagEnv := flags.Bool("new-env", true, "create a new environment for each program") 157 158 cmdLine := RunnerCmd(os.Args[0], "localhost:1234", targets.Linux, targets.AMD64, 0, 0, false, false) 159 args := strings.Split(cmdLine, " ")[1:] 160 if err := flags.Parse(args); err != nil { 161 t.Fatalf("error parsing flags: %v, want: nil", err) 162 } 163 164 if got, want := *flagFwdAddr, "localhost:1234"; got != want { 165 t.Errorf("bad addr: %q, want: %q", got, want) 166 } 167 168 if got, want := *flagOS, targets.Linux; got != want { 169 t.Errorf("bad os: %q, want %q", got, want) 170 } 171 172 if got, want := *flagArch, targets.AMD64; got != want { 173 t.Errorf("bad arch: %q, want: %q", got, want) 174 } 175 176 if got, want := *flagPool, 0; got != want { 177 t.Errorf("bad pool index: %d, want: %d", got, want) 178 } 179 180 if got, want := *flagVM, 0; got != want { 181 t.Errorf("bad vm index: %d, want: %d", got, want) 182 } 183 184 if got, want := *flagThreaded, false; got != want { 185 t.Errorf("bad threaded: %t, want: %t", got, want) 186 } 187 188 if got, want := *flagEnv, false; got != want { 189 t.Errorf("bad new-env: %t, want: %t", got, want) 190 } 191 }