From 93bb1d0d6de4c48580848e4a7b7482b43b060c0a Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Fri, 12 Apr 2019 16:00:15 -0700 Subject: [PATCH 1/7] adb-remount-test: wait-for-screen If we reboot too agressively after a fresh flash either just before test is run, or after vendor is flashed, we run the risk the device will consider it a bad boot and head towards recovery or revert to previous system. Add checks to wait for the screen. This can result in the test reporting issues with boot complete, which will not fail the test currently, but can be used to determine if the device under test is in a boot loop or fragile state. Test: fastboot flashall ; adb-remount-test.sh Bug: 132070014 Change-Id: Ia1b3800c44222cb8fbd9b00e897b32a256996ebc --- fs_mgr/tests/adb-remount-test.sh | 55 ++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/fs_mgr/tests/adb-remount-test.sh b/fs_mgr/tests/adb-remount-test.sh index e6625e74a..711641147 100755 --- a/fs_mgr/tests/adb-remount-test.sh +++ b/fs_mgr/tests/adb-remount-test.sh @@ -366,6 +366,57 @@ any_wait() { inFastboot || inAdb || inRecovery } +wait_for_screen_timeout=900 +[ "USAGE: wait_for_screen [-n] [TIMEOUT] + +-n - echo newline at exit +TIMEOUT - default `format_duration ${wait_for_screen_timeout}`" ] +wait_for_screen() { + exit_function=true + if [ X"-n" = X"${1}" ]; then + exit_function=echo + shift + fi + timeout=${wait_for_screen_timeout} + if [ ${#} -gt 0 ]; then + timeout=${1} + shift + fi + counter=0 + while true; do + if inFastboot; then + fastboot reboot + elif inAdb; then + if [ 0 != ${counter} ]; then + adb_wait + fi + if [ -n "`get_property sys.boot.reason`" ] + then + vals=`get_property | + sed -n 's/[[]sys[.]\(boot_completed\|logbootcomplete\)[]]: [[]\([01]\)[]]$/\1=\2/p'` + if [ "${vals}" = "`echo boot_completed=1 ; echo logbootcomplete=1`" ] + then + sleep 1 + break + fi + if [ "${vals}" = "`echo logbootcomplete=1 ; echo boot_completed=1`" ] + then + sleep 1 + break + fi + fi + fi + counter=`expr ${counter} + 1` + if [ ${counter} -gt ${timeout} ]; then + ${exit_function} + echo "ERROR: wait_for_screen() timed out (`format_duration ${timeout}`)" >&2 + return 1 + fi + sleep 1 + done + ${exit_function} +} + [ "USAGE: adb_root NB: This can be flakey on devices due to USB state @@ -697,6 +748,8 @@ adb_sh ls -l /dev/block/by-name/ /dev/null | esac done +# If reboot too soon after fresh flash, could trip device update failure logic +wait_for_screen # Can we test remount -R command? overlayfs_supported=true if [ "orange" = "`get_property ro.boot.verifiedbootstate`" -a \ @@ -1074,6 +1127,7 @@ elif [ "${ANDROID_PRODUCT_OUT}" = "${ANDROID_PRODUCT_OUT%*/${H}}" ]; then elif [ -z "${ANDROID_HOST_OUT}" ]; then echo "${ORANGE}[ WARNING ]${NORMAL} please run lunch, skipping" else + wait_for_screen adb reboot fastboot &2 T=`adb_date` From dbd99f0d2b956dc0837ec5d051e677ecf287d21a Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Mon, 6 May 2019 09:19:43 -0700 Subject: [PATCH 2/7] adb-remount-test: report usb user on unexpected connection Test: adb-remount-test.sh Bug: 132070014 Change-Id: I1bc4009b71cac4ac4e06df38cc4da77f2819b88b --- fs_mgr/tests/adb-remount-test.sh | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/fs_mgr/tests/adb-remount-test.sh b/fs_mgr/tests/adb-remount-test.sh index 711641147..72fd85c96 100755 --- a/fs_mgr/tests/adb-remount-test.sh +++ b/fs_mgr/tests/adb-remount-test.sh @@ -261,6 +261,13 @@ adb_wait() { return ${ret} } +[ "USAGE: adb_user > /dev/stdout + +Returns: the adb daemon user" ] +adb_user() { + adb_sh echo '${USER}' stdout 2> stderr Assumes referenced right after adb_wait or fastboot_wait failued. @@ -276,7 +283,7 @@ usb_status() { elif inRecovery; then echo "(In recovery mode)" elif inAdb; then - echo "(In adb mode)" + echo "(In adb mode `adb_user`)" else echo "(USB stack borken for ${USB_ADDRESS})" USB_DEVICE=`usb_devnum` @@ -423,11 +430,11 @@ NB: This can be flakey on devices due to USB state Returns: true if device in root state" ] adb_root() { - [ root != "`adb_sh echo '${USER}' /dev/null /dev/null sleep 2 adb_wait 2m && - [ root = "`adb_sh echo '${USER}' /dev/null /dev/null sleep 2 adb_wait 2m && - [ root != "`adb_sh echo '${USER}' /dev/stderr From 00dd058a1585c2eb9946d62aff361040af0d1c7e Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Wed, 22 May 2019 11:00:55 -0700 Subject: [PATCH 3/7] adb-remount-test: check vendor image signature before using When developing and using the adb remount test, if device under test is flashed from another source than the current visible tree, make sure that the vendor image as-built and visible in a sandbox build is not used indiscriminantly. Test: adb-remount-test.sh Bug: 132070014 Change-Id: I30569a7c871f4c4038b0f7f9c05f5f1a5d12c766 --- fs_mgr/tests/adb-remount-test.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs_mgr/tests/adb-remount-test.sh b/fs_mgr/tests/adb-remount-test.sh index 72fd85c96..efc2b3b86 100755 --- a/fs_mgr/tests/adb-remount-test.sh +++ b/fs_mgr/tests/adb-remount-test.sh @@ -1133,6 +1133,11 @@ elif [ "${ANDROID_PRODUCT_OUT}" = "${ANDROID_PRODUCT_OUT%*/${H}}" ]; then echo "${ORANGE}[ WARNING ]${NORMAL} wrong vendor image, skipping" elif [ -z "${ANDROID_HOST_OUT}" ]; then echo "${ORANGE}[ WARNING ]${NORMAL} please run lunch, skipping" +elif ! ( + adb_cat /vendor/build.prop | + cmp -s ${ANDROID_PRODUCT_OUT}/vendor/build.prop + ) >/dev/null 2>/dev/null; then + echo "${ORANGE}[ WARNING ]${NORMAL} vendor image signature mismatch, skipping" else wait_for_screen adb reboot fastboot Date: Wed, 22 May 2019 09:05:40 -0700 Subject: [PATCH 4/7] adb-remount-test: report wait duration Report any unusual durations for how long it took to wait for the device to come back if --print-time flag. Also report the boot reason if unexpected. Test: adb-remount-test.sh Bug: 132070014 Change-Id: I233bbc7b01b025739d7d63191cb62952fa4b7b2a --- fs_mgr/tests/adb-remount-test.sh | 35 +++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/fs_mgr/tests/adb-remount-test.sh b/fs_mgr/tests/adb-remount-test.sh index efc2b3b86..b883dc5c0 100755 --- a/fs_mgr/tests/adb-remount-test.sh +++ b/fs_mgr/tests/adb-remount-test.sh @@ -33,6 +33,7 @@ Conditions: ## Helper Variables ## +EMPTY="" SPACE=" " # A _real_ embedded tab character TAB="`echo | tr '\n' '\t'`" @@ -240,10 +241,13 @@ usb_devnum() { Returns: waits until the device has returned for adb or optional timeout" ] adb_wait() { + local start=`date +%s` + local duration= local ret if [ -n "${1}" ]; then USB_DEVICE=`usb_devnum --next` - echo -n ". . . waiting `format_duration ${1}`" ${ANDROID_SERIAL} ${USB_ADDRESS} ${USB_DEVICE} "${CR}" + duration=`format_duration ${1}` + echo -n ". . . waiting ${duration}" ${ANDROID_SERIAL} ${USB_ADDRESS} ${USB_DEVICE} "${CR}" timeout --preserve-status --signal=KILL ${1} adb wait-for-device 2>/dev/null ret=${?} echo -n " ${CR}" @@ -258,6 +262,35 @@ adb_wait() { echo "${ORANGE}[ WARNING ]${NORMAL} Active slot changed from ${ACTIVE_SLOT} to ${active_slot}" >&2 fi fi + local end=`date +%s` + local diff_time=`expr ${end} - ${start}` + local _print_time=${print_time} + if [ ${diff_time} -lt 15 ]; then + _print_time=false + fi + diff_time=`format_duration ${diff_time}` + if [ "${diff_time}" = "${duration}" ]; then + _print_time=false + fi + + local reason= + if inAdb; then + reason=`get_property ro.boot.bootreason` + fi + case ${reason} in + reboot*) + reason= + ;; + ${EMPTY}) + ;; + *) + reason=" for boot reason ${reason}" + ;; + esac + if ${_print_time} || [ -n "${reason}" ]; then + echo "${BLUE}[ INFO ]${NORMAL} adb wait duration ${diff_time}${reason}" + fi >&2 + return ${ret} } From 53ec0a46498b86bdbe6a426bcd6f960dc57372f5 Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Wed, 22 May 2019 08:22:17 -0700 Subject: [PATCH 5/7] adb-remount-test: parameterize fastboot_wait & adb_wait, increase timeout Increase adb_wait time to 3 minutes since blueline device takes maximum 2:38 (ten samples) to perform a ramdump should an inopportune kernel panic occur. Test: adb-remount-test.sh Bug: 132070014 Change-Id: Icfbb799f9420035a755090c9fc5fc2ee05dd68d3 --- fs_mgr/tests/adb-remount-test.sh | 45 +++++++++++++++++--------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/fs_mgr/tests/adb-remount-test.sh b/fs_mgr/tests/adb-remount-test.sh index b883dc5c0..a5799e8a6 100755 --- a/fs_mgr/tests/adb-remount-test.sh +++ b/fs_mgr/tests/adb-remount-test.sh @@ -51,6 +51,9 @@ print_time=false start_time=`date +%s` ACTIVE_SLOT= +ADB_WAIT=3m +FASTBOOT_WAIT=2m + ## ## Helper Functions ## @@ -466,7 +469,7 @@ adb_root() { [ root != "`adb_user`" ] || return 0 adb root >/dev/null /dev/null sleep 2 - adb_wait 2m && + adb_wait ${ADB_WAIT} && [ root = "`adb_user`" ] } @@ -479,7 +482,7 @@ adb_unroot() { [ root = "`adb_user`" ] || return 0 adb unroot >/dev/null /dev/null sleep 2 - adb_wait 2m && + adb_wait ${ADB_WAIT} && [ root != "`adb_user`" ] } @@ -736,7 +739,7 @@ inFastboot && die "device in fastboot mode" inRecovery && die "device in recovery mode" if ! inAdb; then echo "${ORANGE}[ WARNING ]${NORMAL} device not in adb mode" >&2 - adb_wait 2m + adb_wait ${ADB_WAIT} fi inAdb || die "specified device not in adb mode" isDebuggable || die "device not a debug build" @@ -798,19 +801,19 @@ if [ "orange" = "`get_property ro.boot.verifiedbootstate`" -a \ ${overlayfs_supported} || return 0 inFastboot && fastboot reboot && - adb_wait 2m + adb_wait ${ADB_WAIT} inAdb && adb_root && adb enable-verity >/dev/null 2>/dev/null && adb_reboot && - adb_wait 2m + adb_wait ${ADB_WAIT} } echo "${GREEN}[ RUN ]${NORMAL} Testing adb shell su root remount -R command" >&2 adb_su remount -R system &2 adb_reboot && - adb_wait 2m || + adb_wait ${ADB_WAIT} || die "lost device after reboot after wipe `usb_status`" adb_root || die "lost device after elevation to root after wipe `usb_status`" @@ -933,7 +936,7 @@ if [ X"${D}" != X"${H}" ]; then echo "${GREEN}[ INFO ]${NORMAL} rebooting as requested" >&2 L=`adb_logcat -b all -v nsec -t ${T} 2>&1` adb_reboot && - adb_wait 2m || + adb_wait ${ADB_WAIT} || die "lost device after reboot requested `usb_status`" adb_root || die "lost device after elevation to root `usb_status`" @@ -1098,11 +1101,11 @@ fixup_from_recovery() { inRecovery || return 1 echo "${ORANGE}[ ERROR ]${NORMAL} Device in recovery" >&2 adb reboot &1` adb_reboot && - adb_wait 2m && + adb_wait ${ADB_WAIT} && adb_root || die "failed to reboot" T=`adb_date` @@ -1292,7 +1295,7 @@ if [ -n "${scratch_partition}" ]; then rm ${img} } dd if=/dev/zero of=${img} bs=4096 count=16 2>/dev/null && - fastboot_wait 2m || + fastboot_wait ${FASTBOOT_WAIT} || die "reboot into fastboot `usb_status`" fastboot flash --force ${scratch_partition} ${img} err=${?} @@ -1304,7 +1307,7 @@ if [ -n "${scratch_partition}" ]; then die "can not reboot out of fastboot" [ 0 -eq ${err} ] || die "fastboot flash ${scratch_partition}" - adb_wait 2m && + adb_wait ${ADB_WAIT} && adb_root || die "did not reboot after flash" T=`adb_date` @@ -1314,7 +1317,7 @@ if [ -n "${scratch_partition}" ]; then then echo "${ORANGE}[ WARNING ]${NORMAL} adb disable-verity requires a reboot after partial flash" adb_reboot && - adb_wait 2m && + adb_wait ${ADB_WAIT} && adb_root || die "failed to reboot" T=`adb_date` @@ -1352,12 +1355,12 @@ fixup_from_fastboot() { fastboot --set-active=${ACTIVE_SLOT} fi fastboot reboot - adb_wait 2m + adb_wait ${ADB_WAIT} } # Prerequisite is a prepped device from above. adb_reboot && - adb_wait 2m || + adb_wait ${ADB_WAIT} || fixup_from_fastboot || die "lost device after reboot to ro state `usb_status`" adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null &2 # Prerequisite is a prepped device from above. adb_reboot && - adb_wait 2m || + adb_wait ${ADB_WAIT} || fixup_from_fastboot || die "lost device after reboot to ro state `usb_status`" adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null /dev/null &2 adb_root && adb remount -R && - adb_wait 2m || + adb_wait ${ADB_WAIT} || die "adb remount -R" if [ "orange" != "`get_property ro.boot.verifiedbootstate`" -o \ "2" = "`get_property partition.system.verified`" ]; then From d5f89343b15a206a771d8e47b8f2a56d4dad7a30 Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Wed, 22 May 2019 13:12:21 -0700 Subject: [PATCH 6/7] adb-remount-test: add an avc check Check if adb remount resulted in any unlabeled references just before rebooting the device. Test: adb-remount-test.sh Bug: 129319403 Bug: 132395411 Change-Id: Ica0c14da39773f615d9b5e4cfc4602bd50c70e4e --- fs_mgr/tests/adb-remount-test.sh | 36 ++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/fs_mgr/tests/adb-remount-test.sh b/fs_mgr/tests/adb-remount-test.sh index a5799e8a6..daa950aa2 100755 --- a/fs_mgr/tests/adb-remount-test.sh +++ b/fs_mgr/tests/adb-remount-test.sh @@ -135,10 +135,30 @@ Returns: the logcat output" ] adb_logcat() { echo "${RED}[ INFO ]${NORMAL} logcat ${@}" >&2 && adb logcat "${@}" /dev/stderr + +Returns: worrisome avc violations" ] +avc_check() { + if ! ${overlayfs_supported:-false}; then + return + fi + local L=`adb_logcat -b all -v brief -d \ + -e 'context=u:object_r:unlabeled:s0' 2>/dev/null | + sed -n 's/.*avc: //p' | + sort -u` + if [ -z "${L}" ]; then + return + fi + echo "${ORANGE}[ WARNING ]${NORMAL} unlabeled sepolicy violations:" >&2 + echo "${L}" | + sed 's/^/ /' >&2 +} + [ "USAGE: get_property Returns the property value" ] @@ -177,6 +197,7 @@ adb_cat() { Returns: true if the reboot command succeeded" ] adb_reboot() { + avc_check adb reboot remount-test &2 + avc_check adb_su remount -R system &2 +# Feed log with selinux denials as baseline before overlays +adb_unroot +adb_sh find /system /vendor /dev/null 2>/dev/null +adb_root + D=`adb remount 2>&1` ret=${?} echo "${D}" @@ -1129,6 +1156,9 @@ if ${enforcing}; then B="`adb_cat /vendor/hello 2>&1`" check_eq "cat: /vendor/hello: Permission denied" "${B}" vendor after reboot w/o root echo "${GREEN}[ OK ]${NORMAL} /vendor content correct MAC after reboot" >&2 + # Feed unprivileged log with selinux denials as a result of overlays + wait_for_screen + adb_sh find /system /vendor /dev/null 2>/dev/null fi B="`adb_cat /system/hello`" check_eq "${A}" "${B}" /system after reboot @@ -1140,6 +1170,9 @@ B="`adb_cat /vendor/hello`" check_eq "${A}" "${B}" vendor after reboot echo "${GREEN}[ OK ]${NORMAL} /vendor content remains after reboot" >&2 +# Feed log with selinux denials as a result of overlays +adb_sh find /system /vendor /dev/null 2>/dev/null + # Check if the updated libc.so is persistent after reboot. adb_root && adb pull /system/lib/bootstrap/libc.so ${tempdir}/libc.so.fromdevice >/dev/null || @@ -1176,6 +1209,7 @@ elif ! ( echo "${ORANGE}[ WARNING ]${NORMAL} vendor image signature mismatch, skipping" else wait_for_screen + avc_check adb reboot fastboot &2 + avc_check adb reboot fastboot &2 + avc_check adb_root && adb remount -R && adb_wait ${ADB_WAIT} || From 67788ef8a1ac5c1acce9fb8477b83320a6e02d16 Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Wed, 22 May 2019 14:09:25 -0700 Subject: [PATCH 7/7] adb-remount-test: check devt and inode Check to make sure st_dev and st_ino for the uploaded content is as expected. Test: adb-remount-test Bug: 129319403 Bug: 132395411 Change-Id: I89826fc2740dfd2ead4bcd8988cfbbc315b77b09 --- fs_mgr/tests/adb-remount-test.sh | 73 ++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/fs_mgr/tests/adb-remount-test.sh b/fs_mgr/tests/adb-remount-test.sh index daa950aa2..c52389345 100755 --- a/fs_mgr/tests/adb-remount-test.sh +++ b/fs_mgr/tests/adb-remount-test.sh @@ -655,6 +655,30 @@ EXPECT_EQ() { return 0 } +[ "USAGE: EXPECT_NE [--warning [message]] + +Returns true if lval matches rval" ] +EXPECT_NE() { + local lval="${1}" + local rval="${2}" + shift 2 + local error=1 + local prefix="${RED}[ ERROR ]${NORMAL}" + if [ X"${1}" = X"--warning" ]; then + prefix="${RED}[ WARNING ]${NORMAL}" + error=0 + shift 1 + fi + if [ X"${rval}" = X"${lval}" ]; then + echo "${prefix} did not expect \"${lval}\" ${*}" >&2 + return ${error} + fi + if [ -n "${*}" ] ; then + echo "${prefix} ok \"${lval}\" not \"${rval}\" ${*}" >&2 + fi + return 0 +} + [ "USAGE: check_eq [--warning [message]] Exits if (regex) lval mismatches rval" ] @@ -670,6 +694,21 @@ check_eq() { die "${@}" } +[ "USAGE: check_ne [--warning [message]] + +Exits if lval matches rval" ] +check_ne() { + local lval="${1}" + local rval="${2}" + shift 2 + if [ X"${1}" = X"--warning" ]; then + EXPECT_NE "${lval}" "${rval}" ${*} + return + fi + EXPECT_NE "${lval}" "${rval}" || + die "${@}" +} + [ "USAGE: skip_administrative_mounts [data] < /proc/mounts Filters out all administrative (eg: sysfs) mounts uninteresting to the test" ] @@ -1104,6 +1143,26 @@ check_eq "${A}" "${B}" /system before reboot B="`adb_cat /vendor/hello`" || die "vendor hello" check_eq "${A}" "${B}" /vendor before reboot +SYSTEM_DEVT=`adb_sh stat --format=%D /system/hello &2 +check_eq "${SYSTEM_DEVT}" "`adb_sh stat --format=%D /system/hello /dev/null 2>/dev/null @@ -1286,6 +1353,12 @@ else check_eq "cat: /vendor/hello: No such file or directory" "${B}" \ --warning vendor content after flash vendor fi + + check_eq "${SYSTEM_DEVT}" "`adb_sh stat --format=%D /system/hello