blob: ec68f4b95b32a7365c013c04e6cf72743041c1dd [file] [log] [blame]
// Copyright 2018 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
package main
import (
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/google/syzkaller/pkg/bisect"
"github.com/google/syzkaller/pkg/config"
"github.com/google/syzkaller/pkg/mgrconfig"
)
var (
flagConfig = flag.String("config", "", "bisect config file")
flagCrash = flag.String("crash", "", "dir with crash info")
flagFix = flag.Bool("fix", false, "search for crash fix")
)
type Config struct {
BinDir string `json:"bin_dir"`
KernelRepo string `json:"kernel_repo"`
KernelBranch string `json:"kernel_branch"`
Compiler string `json:"compiler"`
Userspace string `json:"userspace"`
Sysctl string `json:"sysctl"`
Cmdline string `json:"cmdline"`
SyzkallerRepo string `json:"syzkaller_repo"`
Manager json.RawMessage `json:"manager"`
}
func main() {
flag.Parse()
os.Setenv("SYZ_DISABLE_SANDBOXING", "yes")
mycfg := new(Config)
if err := config.LoadFile(*flagConfig, mycfg); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
mgrcfg, err := mgrconfig.LoadPartialData(mycfg.Manager)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
if mgrcfg.Workdir == "" {
mgrcfg.Workdir, err = ioutil.TempDir("", "syz-bisect")
if err != nil {
fmt.Fprintf(os.Stderr, "failed to create temp dir: %v\n", err)
os.Exit(1)
}
defer os.RemoveAll(mgrcfg.Workdir)
}
cfg := &bisect.Config{
Trace: os.Stdout,
Fix: *flagFix,
BinDir: mycfg.BinDir,
DebugDir: *flagCrash,
Kernel: bisect.KernelConfig{
Repo: mycfg.KernelRepo,
Branch: mycfg.KernelBranch,
Userspace: mycfg.Userspace,
Sysctl: mycfg.Sysctl,
Cmdline: mycfg.Cmdline,
},
Syzkaller: bisect.SyzkallerConfig{
Repo: mycfg.SyzkallerRepo,
},
Manager: *mgrcfg,
}
loadString("syzkaller.commit", &cfg.Syzkaller.Commit)
loadString("kernel.commit", &cfg.Kernel.Commit)
loadFile("kernel.config", &cfg.Kernel.Config)
loadFile("repro.syz", &cfg.Repro.Syz)
loadFile("repro.opts", &cfg.Repro.Opts)
bisect.Run(cfg)
}
func loadString(file string, dst *string) {
data, err := ioutil.ReadFile(filepath.Join(*flagCrash, file))
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
*dst = strings.TrimSpace(string(data))
}
func loadFile(file string, dst *[]byte) {
data, err := ioutil.ReadFile(filepath.Join(*flagCrash, file))
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
*dst = data
}