Home | History | Annotate | Download | only in syz-prog2c
      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 	"io/ioutil"
     10 	"os"
     11 	"runtime"
     12 
     13 	"github.com/google/syzkaller/pkg/csource"
     14 	"github.com/google/syzkaller/prog"
     15 	_ "github.com/google/syzkaller/sys"
     16 )
     17 
     18 var (
     19 	flagOS         = flag.String("os", runtime.GOOS, "target os")
     20 	flagArch       = flag.String("arch", runtime.GOARCH, "target arch")
     21 	flagBuild      = flag.Bool("build", false, "also build the generated program")
     22 	flagThreaded   = flag.Bool("threaded", false, "create threaded program")
     23 	flagCollide    = flag.Bool("collide", false, "create collide 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 	flagSandbox    = flag.String("sandbox", "", "sandbox to use (none, setuid, namespace)")
     27 	flagProg       = flag.String("prog", "", "file with program to convert (required)")
     28 	flagFaultCall  = flag.Int("fault_call", -1, "inject fault into this call (0-based)")
     29 	flagFaultNth   = flag.Int("fault_nth", 0, "inject fault on n-th operation (0-based)")
     30 	flagEnableTun  = flag.Bool("tun", false, "set up TUN/TAP interface")
     31 	flagUseTmpDir  = flag.Bool("tmpdir", false, "create a temporary dir and execute inside it")
     32 	flagCgroups    = flag.Bool("cgroups", false, "enable cgroups support")
     33 	flagNetdev     = flag.Bool("netdev", false, "setup various net devices")
     34 	flagResetNet   = flag.Bool("resetnet", false, "reset net namespace after each test")
     35 	flagHandleSegv = flag.Bool("segv", false, "catch and ignore SIGSEGV")
     36 	flagTrace      = flag.Bool("trace", false, "trace syscall results")
     37 )
     38 
     39 func main() {
     40 	flag.Parse()
     41 	if *flagProg == "" {
     42 		flag.PrintDefaults()
     43 		os.Exit(1)
     44 	}
     45 	target, err := prog.GetTarget(*flagOS, *flagArch)
     46 	if err != nil {
     47 		fmt.Fprintf(os.Stderr, "%v", err)
     48 		os.Exit(1)
     49 	}
     50 	data, err := ioutil.ReadFile(*flagProg)
     51 	if err != nil {
     52 		fmt.Fprintf(os.Stderr, "failed to read prog file: %v\n", err)
     53 		os.Exit(1)
     54 	}
     55 	p, err := target.Deserialize(data)
     56 	if err != nil {
     57 		fmt.Fprintf(os.Stderr, "failed to deserialize the program: %v\n", err)
     58 		os.Exit(1)
     59 	}
     60 	opts := csource.Options{
     61 		Threaded:      *flagThreaded,
     62 		Collide:       *flagCollide,
     63 		Repeat:        *flagRepeat != 1,
     64 		RepeatTimes:   *flagRepeat,
     65 		Procs:         *flagProcs,
     66 		Sandbox:       *flagSandbox,
     67 		Fault:         *flagFaultCall >= 0,
     68 		FaultCall:     *flagFaultCall,
     69 		FaultNth:      *flagFaultNth,
     70 		EnableTun:     *flagEnableTun,
     71 		UseTmpDir:     *flagUseTmpDir,
     72 		EnableCgroups: *flagCgroups,
     73 		EnableNetdev:  *flagNetdev,
     74 		ResetNet:      *flagResetNet,
     75 		HandleSegv:    *flagHandleSegv,
     76 		Repro:         false,
     77 		Trace:         *flagTrace,
     78 	}
     79 	src, err := csource.Write(p, opts)
     80 	if err != nil {
     81 		fmt.Fprintf(os.Stderr, "failed to generate C source: %v\n", err)
     82 		os.Exit(1)
     83 	}
     84 	if formatted, err := csource.Format(src); err != nil {
     85 		fmt.Fprintf(os.Stderr, "%v\n", err)
     86 	} else {
     87 		src = formatted
     88 	}
     89 	os.Stdout.Write(src)
     90 	if !*flagBuild {
     91 		return
     92 	}
     93 	bin, err := csource.Build(target, src)
     94 	if err != nil {
     95 		fmt.Fprintf(os.Stderr, "failed to build C source: %v\n", err)
     96 		os.Exit(1)
     97 	}
     98 	os.Remove(bin)
     99 	fmt.Fprintf(os.Stderr, "binary build OK\n")
    100 }
    101