github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/tools/syz-prog2c/prog2c.go (about) 1 // Copyright 2015 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 main 5 6 import ( 7 "flag" 8 "fmt" 9 "log" 10 "os" 11 "runtime" 12 13 "github.com/google/syzkaller/pkg/csource" 14 "github.com/google/syzkaller/pkg/kfuzztest" 15 "github.com/google/syzkaller/prog" 16 _ "github.com/google/syzkaller/sys" 17 ) 18 19 var ( 20 flagOS = flag.String("os", runtime.GOOS, "target os") 21 flagArch = flag.String("arch", runtime.GOARCH, "target arch") 22 flagBuild = flag.Bool("build", false, "also build the generated program") 23 flagThreaded = flag.Bool("threaded", false, "create threaded program") 24 flagRepeat = flag.Int("repeat", 1, "repeat program that many times (<=0 - infinitely)") 25 flagProcs = flag.Int("procs", 1, "number of parallel processes") 26 flagSlowdown = flag.Int("slowdown", 1, "execution slowdown caused by emulation/instrumentation") 27 flagSandbox = flag.String("sandbox", "", "sandbox to use (none, setuid, namespace, android)") 28 flagSandboxArg = flag.Int("sandbox_arg", 0, "argument for executor to customize its behavior") 29 flagProg = flag.String("prog", "", "file with program to convert (required)") 30 flagHandleSegv = flag.Bool("segv", false, "catch and ignore SIGSEGV") 31 flagUseTmpDir = flag.Bool("tmpdir", false, "create a temporary dir and execute inside it") 32 flagTrace = flag.Bool("trace", false, "trace syscall results") 33 flagStrict = flag.Bool("strict", false, "parse input program in strict mode") 34 flagLeak = flag.Bool("leak", false, "do leak checking") 35 flagEnable = flag.String("enable", "none", "enable only listed additional features") 36 flagDisable = flag.String("disable", "none", "enable all additional features except listed") 37 flagVmlinux = flag.String("vmlinux", "", "path to vmlinux binary (required for dynamically discovered calls") 38 ) 39 40 func main() { 41 flag.Usage = func() { 42 flag.PrintDefaults() 43 csource.PrintAvailableFeaturesFlags() 44 } 45 flag.Parse() 46 if *flagProg == "" { 47 flag.Usage() 48 os.Exit(1) 49 } 50 features, err := csource.ParseFeaturesFlags(*flagEnable, *flagDisable, false) 51 if err != nil { 52 log.Fatalf("%v", err) 53 } 54 target, err := prog.GetTarget(*flagOS, *flagArch) 55 if err != nil { 56 fmt.Fprintf(os.Stderr, "%v\n", err) 57 os.Exit(1) 58 } 59 if *flagVmlinux != "" { 60 _, err = kfuzztest.ActivateKFuzzTargets(target, *flagVmlinux) 61 if err != nil { 62 fmt.Fprintf(os.Stderr, "%v\n", err) 63 os.Exit(1) 64 } 65 } 66 data, err := os.ReadFile(*flagProg) 67 if err != nil { 68 fmt.Fprintf(os.Stderr, "failed to read prog file: %v\n", err) 69 os.Exit(1) 70 } 71 mode := prog.NonStrict 72 if *flagStrict { 73 mode = prog.Strict 74 } 75 p, err := target.Deserialize(data, mode) 76 if err != nil { 77 fmt.Fprintf(os.Stderr, "failed to deserialize the program: %v\n", err) 78 os.Exit(1) 79 } 80 opts := csource.Options{ 81 Threaded: *flagThreaded, 82 Repeat: *flagRepeat != 1, 83 RepeatTimes: *flagRepeat, 84 Procs: *flagProcs, 85 Slowdown: *flagSlowdown, 86 Sandbox: *flagSandbox, 87 SandboxArg: *flagSandboxArg, 88 Leak: *flagLeak, 89 NetInjection: features["tun"].Enabled, 90 NetDevices: features["net_dev"].Enabled, 91 NetReset: features["net_reset"].Enabled, 92 Cgroups: features["cgroups"].Enabled, 93 BinfmtMisc: features["binfmt_misc"].Enabled, 94 CloseFDs: features["close_fds"].Enabled, 95 KCSAN: features["kcsan"].Enabled, 96 DevlinkPCI: features["devlink_pci"].Enabled, 97 NicVF: features["nic_vf"].Enabled, 98 USB: features["usb"].Enabled, 99 VhciInjection: features["vhci"].Enabled, 100 Wifi: features["wifi"].Enabled, 101 IEEE802154: features["ieee802154"].Enabled, 102 Sysctl: features["sysctl"].Enabled, 103 Swap: features["swap"].Enabled, 104 UseTmpDir: *flagUseTmpDir, 105 HandleSegv: *flagHandleSegv, 106 Trace: *flagTrace, 107 CallComments: true, 108 } 109 src, err := csource.Write(p, opts) 110 if err != nil { 111 fmt.Fprintf(os.Stderr, "failed to generate C source: %v\n", err) 112 os.Exit(1) 113 } 114 if formatted, err := csource.Format(src); err != nil { 115 fmt.Fprintf(os.Stderr, "%v\n", err) 116 } else { 117 src = formatted 118 } 119 os.Stdout.Write(src) 120 if !*flagBuild { 121 return 122 } 123 bin, err := csource.Build(target, src) 124 if err != nil { 125 fmt.Fprintf(os.Stderr, "failed to build C source: %v\n", err) 126 os.Exit(1) 127 } 128 os.Remove(bin) 129 fmt.Fprintf(os.Stderr, "binary build OK\n") 130 }