aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Artemiev <artemiev@google.com>2022-07-18 11:12:52 -0700
committerDmitry Vyukov <dvyukov@google.com>2022-07-25 11:18:10 +0200
commit003316ca7d8312ac0220bf1e89ced84f5b018f00 (patch)
tree52bef0f99ec2930a12618a18c8b7affead5488f3
parent664c519c76b7466a55b659a722a40aa4dff08998 (diff)
vm/adb: wait for Android boot to finish
executor: removed condition around tun init
-rw-r--r--executor/common_linux.h6
-rw-r--r--pkg/csource/generated.go4
-rw-r--r--vm/adb/adb.go61
3 files changed, 53 insertions, 18 deletions
diff --git a/executor/common_linux.h b/executor/common_linux.h
index 7014f156d..6e9f6a7d4 100644
--- a/executor/common_linux.h
+++ b/executor/common_linux.h
@@ -4179,11 +4179,7 @@ static int do_sandbox_android(int sandbox_arg)
initialize_devlink_pci();
#endif
#if SYZ_EXECUTOR || SYZ_NET_INJECTION
- if (sandbox_arg != 1) {
- // TODO (gArtmv): investigate why fuzzing fails when the line
- // below is executed.
- initialize_tun();
- }
+ initialize_tun();
#endif
#if SYZ_EXECUTOR || SYZ_NET_DEVICES
// TODO(dvyukov): unshare net namespace.
diff --git a/pkg/csource/generated.go b/pkg/csource/generated.go
index fce9fc8ee..77dfcc630 100644
--- a/pkg/csource/generated.go
+++ b/pkg/csource/generated.go
@@ -9814,9 +9814,7 @@ static int do_sandbox_android(int sandbox_arg)
initialize_devlink_pci();
#endif
#if SYZ_EXECUTOR || SYZ_NET_INJECTION
- if (sandbox_arg != 1) {
- initialize_tun();
- }
+ initialize_tun();
#endif
#if SYZ_EXECUTOR || SYZ_NET_DEVICES
initialize_netdevices();
diff --git a/vm/adb/adb.go b/vm/adb/adb.go
index 4e3cfb5d5..7ee38598f 100644
--- a/vm/adb/adb.go
+++ b/vm/adb/adb.go
@@ -176,6 +176,20 @@ var (
devToConsole = make(map[string]string)
)
+func parseAdbOutToInt(out []byte) int {
+ val := 0
+ for _, c := range out {
+ if c >= '0' && c <= '9' {
+ val = val*10 + int(c) - '0'
+ continue
+ }
+ if val != 0 {
+ break
+ }
+ }
+ return val
+}
+
// findConsole returns console file associated with the dev device (e.g. /dev/ttyUSB0).
// This code was tested with Suzy-Q and Android Serial Cable (ASC). For Suzy-Q see:
// https://chromium.googlesource.com/chromiumos/platform/ec/+/master/docs/case_closed_debugging.md
@@ -309,6 +323,40 @@ func (inst *instance) adbWithTimeout(timeout time.Duration, args ...string) ([]b
return out, err
}
+func (inst *instance) waitForBootCompletion() {
+ // ADB connects to a phone and starts syz-fuzzer while the phone is still booting.
+ // This enables syzkaller to create a race condition which in certain cases doesn't
+ // allow the phone to finalize initialization.
+ // To determine whether a system has booted and started all system processes and
+ // services we wait for a process named 'com.android.systemui' to start. It's possible
+ // that in the future a new devices which doesn't have 'systemui' process will be fuzzed
+ // with adb, in this case this code should be modified with a new process name to search for.
+ log.Logf(2, "waiting for boot completion")
+
+ sleepTime := 5
+ sleepDuration := time.Duration(sleepTime) * time.Second
+ maxWaitTime := 60 * 3 // 3 minutes to wait until boot completion
+ maxRetries := maxWaitTime / sleepTime
+ i := 0
+ for ; i < maxRetries; i++ {
+ time.Sleep(sleepDuration)
+
+ if out, err := inst.adb("shell", "pgrep systemui | wc -l"); err == nil {
+ count := parseAdbOutToInt(out)
+ if count != 0 {
+ log.Logf(0, "boot completed")
+ break
+ }
+ } else {
+ log.Logf(0, "failed to execute command 'pgrep systemui | wc -l', %v", err)
+ break
+ }
+ }
+ if i == maxRetries {
+ log.Logf(0, "failed to determine boot completion, can't find 'com.android.systemui' process")
+ }
+}
+
func (inst *instance) repair() error {
// Assume that the device is in a bad state initially and reboot it.
// Ignore errors, maybe we will manage to reboot it anyway.
@@ -338,6 +386,8 @@ func (inst *instance) repair() error {
// Switch to root for userdebug builds.
inst.adb("root")
inst.waitForSSH()
+ inst.waitForBootCompletion()
+
// Mount debugfs.
if _, err := inst.adb("shell", "ls /sys/kernel/debug/kcov"); err != nil {
log.Logf(2, "debugfs was unmounted mounting")
@@ -428,16 +478,7 @@ func (inst *instance) getBatteryLevel(numRetry int) (int, error) {
if err != nil {
return 0, err
}
- val := 0
- for _, c := range out {
- if c >= '0' && c <= '9' {
- val = val*10 + int(c) - '0'
- continue
- }
- if val != 0 {
- break
- }
- }
+ val := parseAdbOutToInt(out)
if val == 0 {
return 0, fmt.Errorf("failed to parse 'dumpsys battery' output: %s", out)
}