From 97b58e7eae01ebe5df5d0bfdff4e6154e7ca869b Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Sat, 17 Jun 2017 14:34:02 +0200 Subject: syz-manager/mgrconfig: move sshkey from vm config to manager config Sshkey is a property of image, which is in manager config. Move sshkey to the same location as image. The motivation for the move is as follows. Continuous build produces an image and the key, both need to be passed manager instance. Continuous build system should not distinguish different VM types and mess with their configs. NOTE FOR USERS: this breaks manager configs again. Hopefully the last time for now. Docs are updated. --- docs/configuration.md | 4 ++-- docs/setup_linux-host_qemu-vm_arm64-kernel.md | 2 +- docs/setup_ubuntu-host_odroid-c2-board_arm64-kernel.md | 4 ++-- docs/setup_ubuntu-host_qemu-vm_x86-64-kernel.md | 2 +- syz-gce/syz-gce.go | 5 +++-- syz-manager/manager.go | 8 +------- syz-manager/mgrconfig/mgrconfig.go | 13 +++++++++++++ syz-manager/mgrconfig/testdata/qemu.cfg | 4 ++-- tools/syz-crush/crush.go | 8 +------- tools/syz-repro/repro.go | 8 +------- vm/adb/adb.go | 2 +- vm/gce/gce.go | 6 ++---- vm/kvm/kvm.go | 2 +- vm/odroid/odroid.go | 11 ++++++----- vm/qemu/qemu.go | 12 +++++------- vm/vmimpl/vmimpl.go | 1 + 16 files changed, 43 insertions(+), 49 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 72f12bea7..180affe19 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -16,6 +16,8 @@ following keys in its top-level object: - `leak`: Detect memory leaks with kmemleak. - `image`: Location of the disk image file for the QEMU instance; a copy of this file is passed as the `-hda` option to `qemu-system-x86_64`. + - `sshkey`: Location (on the host machine) of a root SSH identity to use for communicating with + the virtual machine. - `sandbox` : Sandboxing mode, the following modes are supported: - "none": don't do anything special (has false positives, e.g. due to killing init) - "setuid": impersonate into user nobody (65534), default @@ -31,8 +33,6 @@ following keys in its top-level object: - `kernel`: Location of the `bzImage` file for the kernel to be tested; this is passed as the `-kernel` option to `qemu-system-x86_64`. - `cmdline`: Additional command line options for the booting kernel, for example `root=/dev/sda1`. - - `sshkey`: Location (on the host machine) of an SSH identity to use for communicating with - the virtual machine. - `cpu`: Number of CPUs to simulate in the VM (*not currently used*). - `mem`: Amount of memory (in MiB) for the VM; this is passed as the `-m` option to `qemu-system-x86_64`. diff --git a/docs/setup_linux-host_qemu-vm_arm64-kernel.md b/docs/setup_linux-host_qemu-vm_arm64-kernel.md index 2a08d4144..3d21d8497 100644 --- a/docs/setup_linux-host_qemu-vm_arm64-kernel.md +++ b/docs/setup_linux-host_qemu-vm_arm64-kernel.md @@ -133,6 +133,7 @@ A sample config file that exercises the required options are shown below. Modify "vmlinux": “/path/to/vmlinux", "syzkaller": "/path/to/syzkaller/arm64/", "image": "/path/to/rootfs.ext3", + "sshkey": "/path/to/ida_rsa", "procs": 8, "type": "qemu", "vm": { @@ -141,7 +142,6 @@ A sample config file that exercises the required options are shown below. Modify "qemu_args": "-machine virt -cpu cortex-a57", "cmdline": "console=ttyAMA0 root=/dev/vda", "kernel": “/path/to/Image", - "sshkey": "/path/to/ida_rsa", "cpu": 2, "mem": 2048 } diff --git a/docs/setup_ubuntu-host_odroid-c2-board_arm64-kernel.md b/docs/setup_ubuntu-host_odroid-c2-board_arm64-kernel.md index d8aee0563..899beaaa8 100644 --- a/docs/setup_ubuntu-host_odroid-c2-board_arm64-kernel.md +++ b/docs/setup_ubuntu-host_odroid-c2-board_arm64-kernel.md @@ -300,13 +300,13 @@ Use the following config: "workdir": "/syzkaller/workdir", "vmlinux": "/linux-next/vmlinux", "syzkaller": "/go/src/github.com/google/syzkaller", + "sshkey": "/odroid/ssh/id_rsa", "rpc": "172.16.0.30:0", "sandbox": "namespace", "reproduce": false, "procs": 8, "type": "odroid", "vm": { - "sshkey": "/odroid/ssh/id_rsa", "host_addr": "172.16.0.30", "slave_addr": "172.16.0.31", "console": "/dev/ttyUSB0", @@ -320,7 +320,7 @@ Use the following config: Don't forget to update: - `workdir` (path to the workdir) - `vmlinux` (path to the `vmlinux` binary) - - `vm.sshkey` (path to the generated ssh private key) + - `sshkey` (path to the generated ssh private key) - `vm.console` (serial device you used in `minicom`) - `vm.hub_bus` (number of the bus to which USB hub is connected, view with `lsusb`) - `vm.hub_device` (device number for the USB hub, view with `lsusb`) diff --git a/docs/setup_ubuntu-host_qemu-vm_x86-64-kernel.md b/docs/setup_ubuntu-host_qemu-vm_x86-64-kernel.md index 054ea3b5b..41e87ca88 100644 --- a/docs/setup_ubuntu-host_qemu-vm_x86-64-kernel.md +++ b/docs/setup_ubuntu-host_qemu-vm_x86-64-kernel.md @@ -213,13 +213,13 @@ Create manager config like this: "workdir": "/gopath/src/github.com/google/syzkaller/workdir", "vmlinux": "/linux/upstream/vmlinux", "image": "/image/wheezy.img", + "sshkey": "/image/ssh/id_rsa", "syzkaller": "/gopath/src/github.com/google/syzkaller", "procs": 8, "type": "qemu", "vm": { "count": 4, "kernel": "/linux/arch/x86/boot/bzImage", - "sshkey": "/image/ssh/id_rsa", "cpu": 2, "mem": 2048 } diff --git a/syz-gce/syz-gce.go b/syz-gce/syz-gce.go index f6a9fae1b..df0395af3 100644 --- a/syz-gce/syz-gce.go +++ b/syz-gce/syz-gce.go @@ -480,14 +480,15 @@ func writeManagerConfig(cfg *Config, httpPort int, file string) error { Syzkaller: "gopath/src/github.com/google/syzkaller", Type: "gce", Image: "image/disk.tar.gz", + Sshkey: sshKey, Sandbox: cfg.Sandbox, Procs: cfg.Procs, Enable_Syscalls: cfg.Enable_Syscalls, Disable_Syscalls: cfg.Disable_Syscalls, Cover: true, Reproduce: true, - VM: []byte(fmt.Sprintf(`{"count": %v, "machine_type": %q, "gcs_path": %q, "sshkey": %q}`, - cfg.Machine_Count, cfg.Machine_Type, cfg.GCS_Path, sshKey)), + VM: []byte(fmt.Sprintf(`{"count": %v, "machine_type": %q, "gcs_path": %q}`, + cfg.Machine_Count, cfg.Machine_Type, cfg.GCS_Path)), } data, err := json.MarshalIndent(managerCfg, "", "\t") if err != nil { diff --git a/syz-manager/manager.go b/syz-manager/manager.go index 465cf7aad..d577f5323 100644 --- a/syz-manager/manager.go +++ b/syz-manager/manager.go @@ -115,13 +115,7 @@ func main() { } func RunManager(cfg *mgrconfig.Config, syscalls map[int]bool) { - env := &vm.Env{ - Name: cfg.Name, - Workdir: cfg.Workdir, - Image: cfg.Image, - Debug: *flagDebug, - Config: cfg.VM, - } + env := mgrconfig.CreateVMEnv(cfg, *flagDebug) vmPool, err := vm.Create(cfg.Type, env) if err != nil { Fatalf("%v", err) diff --git a/syz-manager/mgrconfig/mgrconfig.go b/syz-manager/mgrconfig/mgrconfig.go index ace794d97..d6e2b4a2e 100644 --- a/syz-manager/mgrconfig/mgrconfig.go +++ b/syz-manager/mgrconfig/mgrconfig.go @@ -13,6 +13,7 @@ import ( "github.com/google/syzkaller/pkg/config" "github.com/google/syzkaller/pkg/osutil" "github.com/google/syzkaller/sys" + "github.com/google/syzkaller/vm" ) type Config struct { @@ -23,6 +24,7 @@ type Config struct { Vmlinux string Tag string // arbitrary optional tag that is saved along with crash reports (e.g. branch/commit) Image string // linux image for VMs + Sshkey string // root ssh key for the image (may be empty for some VM types) Hub_Addr string Hub_Key string @@ -214,3 +216,14 @@ func parseSuppressions(cfg *Config) error { } return nil } + +func CreateVMEnv(cfg *Config, debug bool) *vm.Env { + return &vm.Env{ + Name: cfg.Name, + Workdir: cfg.Workdir, + Image: cfg.Image, + Sshkey: cfg.Sshkey, + Debug: debug, + Config: cfg.VM, + } +} diff --git a/syz-manager/mgrconfig/testdata/qemu.cfg b/syz-manager/mgrconfig/testdata/qemu.cfg index 9a82f2d8e..62f9ccb1d 100644 --- a/syz-manager/mgrconfig/testdata/qemu.cfg +++ b/syz-manager/mgrconfig/testdata/qemu.cfg @@ -3,6 +3,7 @@ "workdir": "/syzkaller/workdir", "vmlinux": "/linux/vmlinux", "image": "/linux_image/wheezy.img", + "sshkey": "/linux_image/ssh/id_rsa", "syzkaller": "/syzkaller", "disable_syscalls": ["keyctl", "add_key", "request_key"], "suppressions": ["some known bug"], @@ -13,7 +14,6 @@ "cpu": 2, "mem": 2048, "kernel": "/linux/arch/x86/boot/bzImage", - "initrd": "linux/initrd", - "sshkey": "/linux_image/ssh/id_rsa" + "initrd": "linux/initrd" } } diff --git a/tools/syz-crush/crush.go b/tools/syz-crush/crush.go index 6020ab4a2..f5768d0d6 100644 --- a/tools/syz-crush/crush.go +++ b/tools/syz-crush/crush.go @@ -36,13 +36,7 @@ func main() { if len(flag.Args()) != 1 { Fatalf("usage: syz-crush -config=config.file execution.log") } - env := &vm.Env{ - Name: cfg.Name, - Workdir: cfg.Workdir, - Image: cfg.Image, - Debug: false, - Config: cfg.VM, - } + env := mgrconfig.CreateVMEnv(cfg, false) vmPool, err := vm.Create(cfg.Type, env) if err != nil { Fatalf("%v", err) diff --git a/tools/syz-repro/repro.go b/tools/syz-repro/repro.go index 99c826207..d144b88de 100644 --- a/tools/syz-repro/repro.go +++ b/tools/syz-repro/repro.go @@ -37,13 +37,7 @@ func main() { if err != nil { Fatalf("failed to open log file: %v", err) } - env := &vm.Env{ - Name: cfg.Name, - Workdir: cfg.Workdir, - Image: cfg.Image, - Debug: false, - Config: cfg.VM, - } + env := mgrconfig.CreateVMEnv(cfg, false) vmPool, err := vm.Create(cfg.Type, env) if err != nil { Fatalf("%v", err) diff --git a/vm/adb/adb.go b/vm/adb/adb.go index f6bc12328..0daad7fd6 100644 --- a/vm/adb/adb.go +++ b/vm/adb/adb.go @@ -50,7 +50,7 @@ func ctor(env *vmimpl.Env) (vmimpl.Pool, error) { Adb: "adb", } if err := config.LoadData(env.Config, cfg); err != nil { - return nil, err + return nil, fmt.Errorf("failed to parse adb vm config: %v", err) } if _, err := exec.LookPath(cfg.Adb); err != nil { return nil, err diff --git a/vm/gce/gce.go b/vm/gce/gce.go index d0a181250..eeae077a5 100644 --- a/vm/gce/gce.go +++ b/vm/gce/gce.go @@ -34,7 +34,6 @@ type Config struct { Count int // number of VMs to use Machine_Type string // GCE machine type (e.g. "n1-highcpu-2") GCS_Path string // GCS path to upload image - Sshkey string // root ssh key for the image } type Pool struct { @@ -68,7 +67,7 @@ func ctor(env *vmimpl.Env) (vmimpl.Pool, error) { Count: 1, } if err := config.LoadData(env.Config, cfg); err != nil { - return nil, err + return nil, fmt.Errorf("failed to parse gce vm config: %v", err) } if cfg.Count < 1 || cfg.Count > 1000 { return nil, fmt.Errorf("invalid config param count: %v, want [1, 1000]", cfg.Count) @@ -82,7 +81,6 @@ func ctor(env *vmimpl.Env) (vmimpl.Pool, error) { if cfg.GCS_Path == "" { return nil, fmt.Errorf("gcs_path parameter is empty") } - cfg.Sshkey = osutil.Abs(cfg.Sshkey) GCE, err := gce.NewContext() if err != nil { @@ -150,7 +148,7 @@ func (pool *Pool) Create(workdir string, index int) (vmimpl.Instance, error) { pool.GCE.DeleteInstance(name, true) } }() - sshKey := pool.cfg.Sshkey + sshKey := pool.env.Sshkey sshUser := "root" if sshKey == "" { // Assuming image supports GCE ssh fanciness. diff --git a/vm/kvm/kvm.go b/vm/kvm/kvm.go index 5c4c0f036..8f17f260c 100644 --- a/vm/kvm/kvm.go +++ b/vm/kvm/kvm.go @@ -64,7 +64,7 @@ func ctor(env *vmimpl.Env) (vmimpl.Pool, error) { Lkvm: "lkvm", } if err := config.LoadData(env.Config, cfg); err != nil { - return nil, err + return nil, fmt.Errorf("failed to parse kvm vm config: %v", err) } if cfg.Count < 1 || cfg.Count > 1000 { return nil, fmt.Errorf("invalid config param count: %v, want [1, 1000]", cfg.Count) diff --git a/vm/odroid/odroid.go b/vm/odroid/odroid.go index 69c77b9c6..2d1f0482e 100644 --- a/vm/odroid/odroid.go +++ b/vm/odroid/odroid.go @@ -39,7 +39,6 @@ type Config struct { Hub_Bus int // host USB bus number for the USB hub Hub_Device int // host USB device number for the USB hub Hub_Port int // port on the USB hub to which Odroid is connected - Sshkey string // root ssh key for the image } type Pool struct { @@ -49,6 +48,7 @@ type Pool struct { type instance struct { cfg *Config + sshkey string closed chan bool debug bool } @@ -56,7 +56,7 @@ type instance struct { func ctor(env *vmimpl.Env) (vmimpl.Pool, error) { cfg := &Config{} if err := config.LoadData(env.Config, cfg); err != nil { - return nil, err + return nil, fmt.Errorf("failed to parse odroid vm config: %v", err) } if cfg.Host_Addr == "" { return nil, fmt.Errorf("config param host_addr is empty") @@ -76,8 +76,8 @@ func ctor(env *vmimpl.Env) (vmimpl.Pool, error) { if cfg.Hub_Port == 0 { return nil, fmt.Errorf("config param hub_port is empty") } - if !osutil.IsExist(cfg.Sshkey) { - return nil, fmt.Errorf("ssh key '%v' does not exist", cfg.Sshkey) + if !osutil.IsExist(env.Sshkey) { + return nil, fmt.Errorf("ssh key '%v' does not exist", env.Sshkey) } if !osutil.IxExist(cfg.Console) { return nil, fmt.Errorf("console file '%v' does not exist", cfg.Console) @@ -96,6 +96,7 @@ func (pool *Pool) Count() int { func (pool *Pool) Create(workdir string, index int) (vmimpl.Instance, error) { inst := &instance{ cfg: pool.cfg, + sshkey: pool.env.Sshkey, closed: make(chan bool), debug: pool.env.Debug, } @@ -397,7 +398,7 @@ func (inst *instance) Run(timeout time.Duration, stop <-chan bool, command strin func (inst *instance) sshArgs(portArg string) []string { args := []string{ - "-i", inst.cfg.Sshkey, + "-i", inst.sshkey, portArg, "22", "-F", "/dev/null", "-o", "ConnectionAttempts=10", diff --git a/vm/qemu/qemu.go b/vm/qemu/qemu.go index 62fb408f9..a264d00b1 100644 --- a/vm/qemu/qemu.go +++ b/vm/qemu/qemu.go @@ -34,12 +34,11 @@ type Config struct { Count int // number of VMs to use Qemu string // qemu binary name (qemu-system-x86_64 by default) Qemu_Args string // additional command line arguments for qemu binary - Kernel string // e.g. arch/x86/boot/bzImage + Kernel string // kernel for injected boot (e.g. arch/x86/boot/bzImage) Cmdline string // kernel command line (can only be specified with kernel) Initrd string // linux initial ramdisk. (optional) Cpu int // number of VM CPUs Mem int // amount of VM memory in MBs - Sshkey string // root ssh key for the image } type Pool struct { @@ -67,7 +66,7 @@ func ctor(env *vmimpl.Env) (vmimpl.Pool, error) { Qemu: "qemu-system-x86_64", } if err := config.LoadData(env.Config, cfg); err != nil { - return nil, err + return nil, fmt.Errorf("failed to parse qemu vm config: %v", err) } if cfg.Count < 1 || cfg.Count > 1000 { return nil, fmt.Errorf("invalid config param count: %v, want [1, 1000]", cfg.Count) @@ -86,8 +85,8 @@ func ctor(env *vmimpl.Env) (vmimpl.Pool, error) { if !osutil.IsExist(env.Image) { return nil, fmt.Errorf("image file '%v' does not exist", env.Image) } - if !osutil.IsExist(cfg.Sshkey) { - return nil, fmt.Errorf("ssh key '%v' does not exist", cfg.Sshkey) + if !osutil.IsExist(env.Sshkey) { + return nil, fmt.Errorf("ssh key '%v' does not exist", env.Sshkey) } } if cfg.Cpu <= 0 || cfg.Cpu > 1024 { @@ -98,7 +97,6 @@ func ctor(env *vmimpl.Env) (vmimpl.Pool, error) { } cfg.Kernel = osutil.Abs(cfg.Kernel) cfg.Initrd = osutil.Abs(cfg.Initrd) - cfg.Sshkey = osutil.Abs(cfg.Sshkey) pool := &Pool{ cfg: cfg, env: env, @@ -111,7 +109,7 @@ func (pool *Pool) Count() int { } func (pool *Pool) Create(workdir string, index int) (vmimpl.Instance, error) { - sshkey := pool.cfg.Sshkey + sshkey := pool.env.Sshkey if pool.env.Image == "9p" { sshkey = filepath.Join(workdir, "key") keygen := exec.Command("ssh-keygen", "-t", "rsa", "-b", "2048", "-N", "", "-C", "", "-f", sshkey) diff --git a/vm/vmimpl/vmimpl.go b/vm/vmimpl/vmimpl.go index 4c542429c..9d2fff183 100644 --- a/vm/vmimpl/vmimpl.go +++ b/vm/vmimpl/vmimpl.go @@ -48,6 +48,7 @@ type Env struct { Name string Workdir string Image string + Sshkey string Debug bool Config []byte // json-serialized VM-type-specific config } -- cgit mrf-deployment