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  }