mirror of
https://github.com/reactos/syzkaller.git
synced 2024-10-07 09:03:28 +00:00
vm/isolated: update isolated vm
* vm/isolated: update isolated vm Old isolated.go cannot hard reset the target device when the target device is stuck, because it used SSH command to reboot. New isolated.go can reboot the target device using USB hub, so it can reboot the device when its kernel is crashed during fuzzing. It also doesn't require 'CGO' like odroid.go * vm/isolated: set default Host, comment modification * vm/isolated: restore ssh reboot in repair() In the previous commit, ssh reboot is removed. but it should be remained, so this commit restore the ssh reboot. Now, repair() func can reboot the target using ssh or /sys/bus/usb/devices/.../authorized/ * vm/isolated: update USBdev rebooting method and etc, ... - change reboot method from using /bin/sh to file method - change USBDevNum to array type - restore waiting time when rebooting * vm/isolated: update USBdev rebooting method and etc, ... - change reboot method from using '/bin/sh' to file i/o - change USBDevNum to array type - restore waiting time when rebooting * vm/isolated: update USBdev rebooting method and etc, ... - change reboot method from using '/bin/sh' to file i/o - change USBDevNum to array type - restore waiting time when rebooting * vm/isolated: some fixes based on feedback - change variable name: USBDevNum -> USBDevNums, USBAuth -> usbAuth - check whether USBDevNums is empty in ctor(), repair() - move usbAuth declaration from Create() to repair() * vm/isolated: remove empty line * vm/isolated: fix some conditions * vm/isolated: change comment, add validate length of USBDevNums * vm/isolated: check whether the len(USBDevNums) and len(Targets) is same * vm/isolated: change repair() func based on review - wait 30*time.Minute even if TargetReboot is not set. - reduce/combine logs - e -> err * vm/isolated: In repair(), print error log and return error when ssh is failed
This commit is contained in:
parent
6738e0b30b
commit
ddc3e85997
64
vm/isolated/isolated.go
Normal file → Executable file
64
vm/isolated/isolated.go
Normal file → Executable file
@ -24,9 +24,11 @@ func init() {
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Targets []string `json:"targets"` // target machines: (hostname|ip)(:port)?
|
||||
TargetDir string `json:"target_dir"` // directory to copy/run on target
|
||||
TargetReboot bool `json:"target_reboot"` // reboot target on repair
|
||||
Host string `json:"host"` // host ip addr
|
||||
Targets []string `json:"targets"` // target machines: (hostname|ip)(:port)?
|
||||
TargetDir string `json:"target_dir"` // directory to copy/run on target
|
||||
TargetReboot bool `json:"target_reboot"` // reboot target on repair
|
||||
USBDevNums []string `json:"usb_device_num"` // /sys/bus/usb/devices/
|
||||
}
|
||||
|
||||
type Pool struct {
|
||||
@ -39,6 +41,7 @@ type instance struct {
|
||||
os string
|
||||
targetAddr string
|
||||
targetPort int
|
||||
index int
|
||||
closed chan bool
|
||||
debug bool
|
||||
sshUser string
|
||||
@ -51,6 +54,9 @@ func ctor(env *vmimpl.Env) (vmimpl.Pool, error) {
|
||||
if err := config.LoadData(env.Config, cfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if cfg.Host == "" {
|
||||
cfg.Host = "127.0.0.1"
|
||||
}
|
||||
if len(cfg.Targets) == 0 {
|
||||
return nil, fmt.Errorf("config param targets is empty")
|
||||
}
|
||||
@ -62,9 +68,17 @@ func ctor(env *vmimpl.Env) (vmimpl.Pool, error) {
|
||||
return nil, fmt.Errorf("bad target %q: %v", target, err)
|
||||
}
|
||||
}
|
||||
if len(cfg.USBDevNums) > 0 {
|
||||
if len(cfg.USBDevNums) != len(cfg.Targets) {
|
||||
return nil, fmt.Errorf("the number of Targets and the number of USBDevNums should be same")
|
||||
}
|
||||
}
|
||||
if env.Debug && len(cfg.Targets) > 1 {
|
||||
log.Logf(0, "limiting number of targets from %v to 1 in debug mode", len(cfg.Targets))
|
||||
cfg.Targets = cfg.Targets[:1]
|
||||
if len(cfg.USBDevNums) > 1 {
|
||||
cfg.USBDevNums = cfg.USBDevNums[:1]
|
||||
}
|
||||
}
|
||||
pool := &Pool{
|
||||
cfg: cfg,
|
||||
@ -84,6 +98,7 @@ func (pool *Pool) Create(workdir string, index int) (vmimpl.Instance, error) {
|
||||
os: pool.env.OS,
|
||||
targetAddr: targetAddr,
|
||||
targetPort: targetPort,
|
||||
index: index,
|
||||
closed: make(chan bool),
|
||||
debug: pool.env.Debug,
|
||||
sshUser: pool.env.SSHUser,
|
||||
@ -99,6 +114,9 @@ func (pool *Pool) Create(workdir string, index int) (vmimpl.Instance, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Remount to writable.
|
||||
inst.ssh("mount -o remount,rw /")
|
||||
|
||||
// Create working dir if doesn't exist.
|
||||
inst.ssh("mkdir -p '" + inst.cfg.TargetDir + "'")
|
||||
|
||||
@ -117,7 +135,7 @@ func (inst *instance) Forward(port int) (string, error) {
|
||||
return "", fmt.Errorf("isolated: Forward port is zero")
|
||||
}
|
||||
inst.forwardPort = port
|
||||
return fmt.Sprintf("127.0.0.1:%v", port), nil
|
||||
return fmt.Sprintf(inst.cfg.Host+":%v", port), nil
|
||||
}
|
||||
|
||||
func (inst *instance) ssh(command string) error {
|
||||
@ -175,26 +193,36 @@ func (inst *instance) repair() error {
|
||||
log.Logf(2, "isolated: trying to ssh")
|
||||
if err := inst.waitForSSH(30 * time.Minute); err == nil {
|
||||
if inst.cfg.TargetReboot {
|
||||
log.Logf(2, "isolated: trying to reboot")
|
||||
inst.ssh("reboot") // reboot will return an error, ignore it
|
||||
if err := inst.waitForReboot(5 * 60); err != nil {
|
||||
log.Logf(2, "isolated: machine did not reboot")
|
||||
return err
|
||||
if len(inst.cfg.USBDevNums) > 0 {
|
||||
log.Logf(2, "isolated: trying to reboot by USB authorization")
|
||||
usbAuth := fmt.Sprintf("%s%s%s", "/sys/bus/usb/devices/", inst.cfg.USBDevNums[inst.index], "/authorized")
|
||||
if err := ioutil.WriteFile(usbAuth, []byte("0"), 0); err != nil {
|
||||
log.Logf(2, "isolated: failed to turn off the device")
|
||||
return err
|
||||
}
|
||||
if err := ioutil.WriteFile(usbAuth, []byte("1"), 0); err != nil {
|
||||
log.Logf(2, "isolated: failed to turn on the device")
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
log.Logf(2, "isolated: ssh succeeded, trying to reboot by ssh")
|
||||
inst.ssh("reboot") // reboot will return an error, ignore it
|
||||
}
|
||||
log.Logf(2, "isolated: rebooted wait for comeback")
|
||||
if err := inst.waitForSSH(30 * time.Minute); err != nil {
|
||||
log.Logf(2, "isolated: machine did not comeback")
|
||||
return err
|
||||
}
|
||||
log.Logf(2, "isolated: reboot succeeded")
|
||||
} else {
|
||||
log.Logf(2, "isolated: ssh succeeded")
|
||||
}
|
||||
if err := inst.waitForReboot(5 * 60); err != nil {
|
||||
log.Logf(2, "isolated: machine did not reboot")
|
||||
return err
|
||||
}
|
||||
log.Logf(2, "isolated: rebooted wait for comeback")
|
||||
if err := inst.waitForSSH(30 * time.Minute); err != nil {
|
||||
log.Logf(0, "isolated: machine did not comeback")
|
||||
return err
|
||||
}
|
||||
log.Logf(2, "isolated: reboot succeeded")
|
||||
} else {
|
||||
log.Logf(2, "isolated: ssh failed")
|
||||
return fmt.Errorf("SSH failed")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user