syz-manager/mgrconfig: explicitly specify target in config

Add target config parameter (e.g. linux/amd64) which controls target OS/arch.
No more explicit assumptions about target.
This commit is contained in:
Dmitry Vyukov 2017-09-13 20:40:27 +02:00
parent 34bc139642
commit f7b1163afb
23 changed files with 121 additions and 41 deletions

View File

@ -25,6 +25,7 @@ bin/syz-manager: Mach-O 64-bit executable x86_64
- Create config with `"type": "adb"` and specify adb devices to use. For example:
```
{
"target": "linux/arm64",
"http": "localhost:50000",
"workdir": "/gopath/src/github.com/google/syzkaller/workdir",
"syzkaller": "/gopath/src/github.com/google/syzkaller",

View File

@ -78,6 +78,7 @@ make
Use the following config:
```
{
"target": "linux/amd64",
"http": "127.0.0.1:56741",
"rpc": "127.0.0.1:0",
"sshkey" : "/path/to/optional/sshkey",
@ -95,6 +96,7 @@ Use the following config:
```
Don't forget to update:
- `target` (target OS/arch)
- `workdir` (path to the workdir)
- `vmlinux` (path to the `vmlinux` binary)
- `sshkey` You can setup an sshkey (optional)

View File

@ -139,6 +139,7 @@ A sample config file that exercises the required options are shown below. Modify
```
{
"name": "QEMU-aarch64",
"target": "linux/arm64",
"http": ":56700",
"workdir": "/path/to/a/dir/to/store/syzkaller/corpus”,
"vmlinux": “/path/to/vmlinux",

View File

@ -296,6 +296,7 @@ $PREFIX/bin/aarch64-linux-gcc executor/executor.cc -O1 -g -Wall -static -o bin/s
Use the following config:
```
{
"target": "linux/arm64",
"http": "127.0.0.1:56741",
"workdir": "/syzkaller/workdir",
"vmlinux": "/linux-next/vmlinux",

View File

@ -209,6 +209,7 @@ make
Create manager config like this:
```
{
"target": "linux/amd64",
"http": "127.0.0.1:56741",
"workdir": "/gopath/src/github.com/google/syzkaller/workdir",
"vmlinux": "/linux/upstream/vmlinux",

View File

@ -8,6 +8,7 @@ import (
"math/rand"
"os"
"reflect"
"runtime"
"testing"
"time"
@ -16,6 +17,10 @@ import (
_ "github.com/google/syzkaller/sys"
)
func init() {
prog.SetDefaultTarget("linux", runtime.GOARCH)
}
func initTest(t *testing.T) (rand.Source, int) {
t.Parallel()
iters := 1

View File

@ -4,6 +4,7 @@
package host
import (
"runtime"
"syscall"
"testing"
@ -11,6 +12,10 @@ import (
_ "github.com/google/syzkaller/sys"
)
func init() {
prog.SetDefaultTarget("linux", runtime.GOARCH)
}
func TestLog(t *testing.T) {
t.Parallel()
// Dump for manual inspection.

View File

@ -7,6 +7,7 @@ import (
"math/rand"
"os"
"path/filepath"
"runtime"
"testing"
"time"
@ -18,6 +19,10 @@ import (
const timeout = 10 * time.Second
func init() {
prog.SetDefaultTarget("linux", runtime.GOARCH)
}
func buildExecutor(t *testing.T) string {
return buildProgram(t, filepath.FromSlash("../../executor/executor.cc"))
}

View File

@ -7,8 +7,6 @@ import (
"bytes"
"fmt"
"testing"
//. "github.com/google/syzkaller/prog"
//_ "github.com/google/syzkaller/sys"
)
func TestGeneration(t *testing.T) {

View File

@ -5,6 +5,7 @@ package prog_test
import (
"bytes"
"runtime"
"strings"
"testing"
@ -12,6 +13,10 @@ import (
_ "github.com/google/syzkaller/sys"
)
func init() {
SetDefaultTarget("linux", runtime.GOARCH)
}
func TestAssignSizeRandom(t *testing.T) {
rs, iters := InitTest(t)
for i := 0; i < iters; i++ {

View File

@ -66,7 +66,11 @@ func SetDefaultTarget(OS, arch string) error {
key := OS + "/" + arch
target := targets[key]
if target == nil {
return fmt.Errorf("unknown target: %v", key)
var supported []string
for _, t := range targets {
supported = append(supported, fmt.Sprintf("%v/%v", t.OS, t.Arch))
}
return fmt.Errorf("unknown target: %v (supported: %v)", key, supported)
}
if len(Syscalls) != 0 {
return fmt.Errorf("default target is already set")

View File

@ -4,14 +4,5 @@
package sys
import (
"runtime"
"github.com/google/syzkaller/prog"
_ "github.com/google/syzkaller/sys/linux"
)
func init() {
if err := prog.SetDefaultTarget("linux", runtime.GOARCH); err != nil {
panic(err)
}
}

View File

@ -309,6 +309,14 @@ func (mgr *Manager) writeConfig(info *BuildInfo) (string, error) {
if err != nil {
return "", err
}
if mgrcfg.Target == "" {
// TODO(dvyukov): temporal measure to handle upgrade.
// Remove this once ci configs have targets.
mgrcfg.Target = "linux/amd64"
mgrcfg.TargetOS = "linux"
mgrcfg.TargetVMArch = "amd64"
mgrcfg.TargetArch = "amd64"
}
current := mgr.currentDir
if mgr.dash != nil {
mgrcfg.Tag = info.Tag
@ -344,7 +352,7 @@ func (mgr *Manager) writeConfig(info *BuildInfo) (string, error) {
if err := config.SaveFile(configFile, mgrcfg); err != nil {
return "", err
}
if _, _, err := mgrconfig.LoadFile(configFile); err != nil {
if _, err := mgrconfig.LoadFile(configFile); err != nil {
return "", err
}
return configFile, nil

View File

@ -105,6 +105,10 @@ func main() {
}
Logf(0, "fuzzer started")
if err := prog.SetDefaultTarget(runtime.GOOS, runtime.GOARCH); err != nil {
Fatalf("%v", err)
}
go func() {
// Handles graceful preemption on GCE.
c := make(chan os.Signal, 1)
@ -413,7 +417,7 @@ func buildCallList(enabledCalls string) map[*prog.Syscall]bool {
for _, id := range strings.Split(enabledCalls, ",") {
n, err := strconv.ParseUint(id, 10, 64)
if err != nil || n >= uint64(len(prog.Syscalls)) {
panic(fmt.Sprintf("invalid syscall in -calls flag: '%v", id))
panic(fmt.Sprintf("invalid syscall in -calls flag: %v", id))
}
calls[prog.Syscalls[n]] = true
}

View File

@ -110,7 +110,14 @@ type Crash struct {
func main() {
flag.Parse()
EnableLogCaching(1000, 1<<20)
cfg, syscalls, err := mgrconfig.LoadFile(*flagConfig)
cfg, err := mgrconfig.LoadFile(*flagConfig)
if err != nil {
Fatalf("%v", err)
}
if err := prog.SetDefaultTarget(cfg.TargetOS, cfg.TargetArch); err != nil {
Fatalf("%v", err)
}
syscalls, err := mgrconfig.ParseEnabledSyscalls(cfg)
if err != nil {
Fatalf("%v", err)
}

View File

@ -19,6 +19,7 @@ import (
type Config struct {
Name string // Instance name (used for identification and as GCE instance prefix)
Target string // Target OS/arch, e.g. "linux/arm64" or "linux/amd64/386" (amd64 OS with 386 test process)
Http string // TCP address to serve HTTP stats page (e.g. "localhost:50000")
Rpc string // TCP address to serve RPC for fuzzer processes (optional)
Workdir string
@ -60,13 +61,17 @@ type Config struct {
// Implementation details beyond this point.
ParsedSuppressions []*regexp.Regexp `json:"-"`
ParsedIgnores []*regexp.Regexp `json:"-"`
// Parsed Target:
TargetOS string `json:"-"`
TargetArch string `json:"-"`
TargetVMArch string `json:"-"`
}
func LoadData(data []byte) (*Config, map[int]bool, error) {
func LoadData(data []byte) (*Config, error) {
return load(data, "")
}
func LoadFile(filename string) (*Config, map[int]bool, error) {
func LoadFile(filename string) (*Config, error) {
return load(nil, filename)
}
@ -80,45 +85,60 @@ func DefaultValues() *Config {
}
}
func load(data []byte, filename string) (*Config, map[int]bool, error) {
func load(data []byte, filename string) (*Config, error) {
cfg := DefaultValues()
if data != nil {
if err := config.LoadData(data, cfg); err != nil {
return nil, nil, err
return nil, err
}
} else {
if err := config.LoadFile(filename, cfg); err != nil {
return nil, nil, err
return nil, err
}
}
if cfg.Target == "" {
return nil, fmt.Errorf("config param target is empty")
}
targetParts := strings.Split(cfg.Target, "/")
if len(targetParts) != 2 && len(targetParts) != 3 {
return nil, fmt.Errorf("bad config param target")
}
cfg.TargetOS = targetParts[0]
cfg.TargetVMArch = targetParts[1]
cfg.TargetArch = targetParts[1]
if len(targetParts) == 3 {
cfg.TargetArch = targetParts[2]
}
if !osutil.IsExist(filepath.Join(cfg.Syzkaller, "bin/syz-fuzzer")) {
return nil, nil, fmt.Errorf("bad config syzkaller param: can't find bin/syz-fuzzer")
return nil, fmt.Errorf("bad config syzkaller param: can't find bin/syz-fuzzer")
}
if !osutil.IsExist(filepath.Join(cfg.Syzkaller, "bin/syz-executor")) {
return nil, nil, fmt.Errorf("bad config syzkaller param: can't find bin/syz-executor")
return nil, fmt.Errorf("bad config syzkaller param: can't find bin/syz-executor")
}
if !osutil.IsExist(filepath.Join(cfg.Syzkaller, "bin/syz-execprog")) {
return nil, nil, fmt.Errorf("bad config syzkaller param: can't find bin/syz-execprog")
return nil, fmt.Errorf("bad config syzkaller param: can't find bin/syz-execprog")
}
if cfg.Http == "" {
return nil, nil, fmt.Errorf("config param http is empty")
return nil, fmt.Errorf("config param http is empty")
}
if cfg.Workdir == "" {
return nil, nil, fmt.Errorf("config param workdir is empty")
return nil, fmt.Errorf("config param workdir is empty")
}
if cfg.Vmlinux == "" {
return nil, nil, fmt.Errorf("config param vmlinux is empty")
return nil, fmt.Errorf("config param vmlinux is empty")
}
if cfg.Type == "" {
return nil, nil, fmt.Errorf("config param type is empty")
return nil, fmt.Errorf("config param type is empty")
}
if cfg.Procs < 1 || cfg.Procs > 32 {
return nil, nil, fmt.Errorf("bad config param procs: '%v', want [1, 32]", cfg.Procs)
return nil, fmt.Errorf("bad config param procs: '%v', want [1, 32]", cfg.Procs)
}
switch cfg.Sandbox {
case "none", "setuid", "namespace":
default:
return nil, nil, fmt.Errorf("config param sandbox must contain one of none/setuid/namespace")
return nil, fmt.Errorf("config param sandbox must contain one of none/setuid/namespace")
}
cfg.Workdir = osutil.Abs(cfg.Workdir)
@ -128,28 +148,23 @@ func load(data []byte, filename string) (*Config, map[int]bool, error) {
cfg.Kernel_Src = filepath.Dir(cfg.Vmlinux) // assume in-tree build by default
}
syscalls, err := parseSyscalls(cfg)
if err != nil {
return nil, nil, err
}
if err := parseSuppressions(cfg); err != nil {
return nil, nil, err
return nil, err
}
if cfg.Hub_Client != "" && (cfg.Name == "" || cfg.Hub_Addr == "" || cfg.Hub_Key == "") {
return nil, nil, fmt.Errorf("hub_client is set, but name/hub_addr/hub_key is empty")
return nil, fmt.Errorf("hub_client is set, but name/hub_addr/hub_key is empty")
}
if cfg.Dashboard_Client != "" && (cfg.Name == "" ||
cfg.Dashboard_Addr == "" ||
cfg.Dashboard_Key == "") {
return nil, nil, fmt.Errorf("dashboard_client is set, but name/dashboard_addr/dashboard_key is empty")
return nil, fmt.Errorf("dashboard_client is set, but name/dashboard_addr/dashboard_key is empty")
}
return cfg, syscalls, nil
return cfg, nil
}
func parseSyscalls(cfg *Config) (map[int]bool, error) {
func ParseEnabledSyscalls(cfg *Config) (map[int]bool, error) {
match := func(call *prog.Syscall, str string) bool {
if str == call.CallName || str == call.Name {
return true

View File

@ -1,4 +1,5 @@
{
"target": "linux/amd64",
"http": "myhost.com:56741",
"workdir": "/syzkaller/workdir",
"vmlinux": "/linux/vmlinux",

View File

@ -19,6 +19,7 @@ import (
"time"
. "github.com/google/syzkaller/pkg/log"
"github.com/google/syzkaller/prog"
"github.com/google/syzkaller/syz-manager/mgrconfig"
"github.com/google/syzkaller/vm"
)
@ -29,13 +30,16 @@ var (
func main() {
flag.Parse()
cfg, _, err := mgrconfig.LoadFile(*flagConfig)
cfg, err := mgrconfig.LoadFile(*flagConfig)
if err != nil {
Fatalf("%v", err)
}
if len(flag.Args()) != 1 {
Fatalf("usage: syz-crush -config=config.file execution.log")
}
if err := prog.SetDefaultTarget(cfg.TargetOS, cfg.TargetArch); err != nil {
Fatalf("%v", err)
}
env := mgrconfig.CreateVMEnv(cfg, false)
vmPool, err := vm.Create(cfg.Type, env)
if err != nil {

View File

@ -13,6 +13,7 @@ import (
"io/ioutil"
"os"
"os/signal"
"runtime"
"sync"
"sync/atomic"
"syscall"
@ -45,6 +46,10 @@ func main() {
os.Exit(1)
}
if err := prog.SetDefaultTarget(runtime.GOOS, runtime.GOARCH); err != nil {
Fatalf("%v", err)
}
var progs []*prog.Prog
for _, fn := range flag.Args() {
data, err := ioutil.ReadFile(fn)

View File

@ -10,6 +10,7 @@ import (
"io/ioutil"
"math/rand"
"os"
"runtime"
"time"
"github.com/google/syzkaller/prog"
@ -26,6 +27,10 @@ func main() {
fmt.Fprintf(os.Stderr, "usage: mutate program\n")
os.Exit(1)
}
if err := prog.SetDefaultTarget(runtime.GOOS, runtime.GOARCH); err != nil {
fmt.Fprintf(os.Stderr, "%v", err)
os.Exit(1)
}
data, err := ioutil.ReadFile(flag.Arg(0))
if err != nil {
fmt.Fprintf(os.Stderr, "failed to read prog file: %v\n", err)

View File

@ -8,6 +8,7 @@ import (
"fmt"
"io/ioutil"
"os"
"runtime"
"github.com/google/syzkaller/pkg/csource"
"github.com/google/syzkaller/prog"
@ -35,6 +36,10 @@ func main() {
flag.PrintDefaults()
os.Exit(1)
}
if err := prog.SetDefaultTarget(runtime.GOOS, runtime.GOARCH); err != nil {
fmt.Fprintf(os.Stderr, "%v", err)
os.Exit(1)
}
data, err := ioutil.ReadFile(*flagProg)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to read prog file: %v\n", err)

View File

@ -14,6 +14,7 @@ import (
"github.com/google/syzkaller/pkg/csource"
. "github.com/google/syzkaller/pkg/log"
"github.com/google/syzkaller/pkg/repro"
"github.com/google/syzkaller/prog"
"github.com/google/syzkaller/syz-manager/mgrconfig"
"github.com/google/syzkaller/vm"
)
@ -26,7 +27,7 @@ var (
func main() {
os.Args = append(append([]string{}, os.Args[0], "-v=10"), os.Args[1:]...)
flag.Parse()
cfg, _, err := mgrconfig.LoadFile(*flagConfig)
cfg, err := mgrconfig.LoadFile(*flagConfig)
if err != nil {
Fatalf("%v", err)
}
@ -37,6 +38,9 @@ func main() {
if err != nil {
Fatalf("failed to open log file: %v", err)
}
if err := prog.SetDefaultTarget(cfg.TargetOS, cfg.TargetArch); err != nil {
Fatalf("%v", err)
}
env := mgrconfig.CreateVMEnv(cfg, false)
vmPool, err := vm.Create(cfg.Type, env)
if err != nil {

View File

@ -37,6 +37,9 @@ const programLength = 30
func main() {
flag.Parse()
if err := prog.SetDefaultTarget(runtime.GOOS, runtime.GOARCH); err != nil {
Fatalf("%v", err)
}
corpus := readCorpus()
Logf(0, "parsed %v programs", len(corpus))
if !*flagGenerate && len(corpus) == 0 {