From bbe33f7826c292893ff296983681cfcc283ab5b0 Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Wed, 13 Feb 2019 13:06:15 -0800 Subject: [PATCH] fs_mgr: harden adb-remount-test.sh Harden adb-remount-test.sh script. Add --no-color and --color options. Allows --serial to be passed in. Add a recovery handler that restores the device to verity enabled if possible. List the partitions sizes as they may be relevant to triaging errors. Allow for devices that have a mixed set of remounts, some direct, some with overlayfs. Allow two scripts to run at the same time on a host machine targetting different devices. Detect if wrong adb is used for adb reboot-fastboot. Add a build target for adb-remount-test.sh so that the script is landed into the host tools bin for easy pickup. Test: adb-remount-test.sh Bug: 123079041 Change-Id: I6369a245a656419067ec4350a4dbdf78c9b0533e --- fs_mgr/tests/Android.bp | 17 +++ fs_mgr/tests/adb-remount-test.sh | 231 ++++++++++++++++++++++++------- 2 files changed, 198 insertions(+), 50 deletions(-) diff --git a/fs_mgr/tests/Android.bp b/fs_mgr/tests/Android.bp index ea12e96f3..565597af7 100644 --- a/fs_mgr/tests/Android.bp +++ b/fs_mgr/tests/Android.bp @@ -36,3 +36,20 @@ cc_test { "-Werror", ], } + +cc_prebuilt_binary { + name: "adb-remount-test.sh", + srcs: ["adb-remount-test.sh"], + target: { + darwin: { + enabled: false, + }, + windows: { + enabled: false, + }, + android: { + enabled: false, + }, + }, + host_supported: true, +} diff --git a/fs_mgr/tests/adb-remount-test.sh b/fs_mgr/tests/adb-remount-test.sh index 7fc951831..e4ff76584 100755 --- a/fs_mgr/tests/adb-remount-test.sh +++ b/fs_mgr/tests/adb-remount-test.sh @@ -11,23 +11,23 @@ ## USAGE ## -USAGE="USAGE: `basename ${0}` [-s ] +USAGE="USAGE: `basename ${0}` [--help] [--serial ] [--color] -adb remount tests (overlayfs focus) +adb remount tests + +--help This help +--serial Specify device (must if multiple are present) +--color Dress output with highlighting colors Conditions: - Must be a userdebug build. - Must be in adb mode. - - Kernel must have overlayfs enabled and patched to support override_creds. - - Must have either squashfs, ext4-dedupe or right-sized partitions. - - Minimum expectation system and vender are overlayfs covered partitions. + - Also tests overlayfs + - Kernel must have overlayfs enabled and patched to support override_creds. + - Must have either erofs, squashfs, ext4-dedupe or full partitions. + - Minimum expectation system and vender are overlayfs covered partitions. " -if [ X"${1}" = X"--help" -o X"${1}" = X"-h" -o X"${1}" = X"-?" ]; then - echo "${USAGE}" >&2 - exit 0 -fi - ## ## Helper Variables ## @@ -44,6 +44,7 @@ RED="${ESCAPE}[38;5;196m" ORANGE="${ESCAPE}[38;5;255:165:0m" BLUE="${ESCAPE}[35m" NORMAL="${ESCAPE}[0m" +TMPDIR=${TMPDIR:-/tmp} ## ## Helper Functions @@ -293,13 +294,22 @@ fastboot_getvar() { echo ${O} >&2 } +[ "USAGE: restore + +Do nothing: should be redefined when necessary. Called after cleanup. + +Returns: reverses configurations" ] +restore() { + true +} + [ "USAGE: cleanup Do nothing: should be redefined when necessary -Returns: cleans up any latent resources, reverses configurations" ] -cleanup () { - : +Returns: cleans up any latent resources" ] +cleanup() { + true } [ "USAGE: die [-d|-t ] [message] >/dev/stderr @@ -321,6 +331,7 @@ die() { fi echo "${RED}[ FAILED ]${NORMAL} ${@}" >&2 cleanup + restore exit 1 } @@ -413,9 +424,48 @@ skip_unrelated_mounts() { ## MAINLINE ## -if [ X"-s" = X"${1}" -a -n "${2}" ]; then - export ANDROID_SERIAL="${2}" - shift 2 +OPTIONS=`getopt --alternative --unquoted --longoptions help,serial:,colour,color,no-colour,no-color -- "?hs:" ${*}` || + ( echo "${USAGE}" >&2 ; false ) || + die "getopt failure" +set -- ${OPTIONS} + +color=false +while [ ${#} -gt 0 ]; do + case ${1} in + -h | --help | -\?) + echo "${USAGE}" >&2 + exit 0 + ;; + -s | --serial) + export ANDROID_SERIAL=${2} + shift + ;; + --color | --colour) + color=true + ;; + --no-color | --no-colour) + color=false + ;; + --) + shift + break + ;; + -*) + echo "${USAGE}" >&2 + die "${0}: error unknown option ${1}" + ;; + *) + break + ;; + esac + shift +done +if ! ${color}; then + GREEN="" + RED="" + ORANGE="" + BLUE="" + NORMAL="" fi inFastboot && die "device in fastboot mode" @@ -451,15 +501,43 @@ BUILD_DESCRIPTION=`get_property ro.build.description` [ -z "${BUILD_DESCRIPTION}" ] || echo "${BLUE}[ INFO ]${NORMAL} ${BUILD_DESCRIPTION}" >&2 -VERITY_WAS_ENABLED=false +# Report existing partition sizes +adb_sh ls -l /dev/block/by-name/ /dev/null | + sed -n 's@.* \([^ ]*\) -> /dev/block/\([^ ]*\)$@\1 \2@p' | + while read name device; do + case ${name} in + system_[ab] | system | vendor_[ab] | vendor | super | cache) + case ${device} in + sd*) + device=${device%%[0-9]*}/${device} + ;; + esac + size=`adb_su cat /sys/block/${device}/size 2>/dev/null &2 + ;; + esac + done + +# Can we test remount -R command? +overlayfs_supported=true if [ "orange" = "`get_property ro.boot.verifiedbootstate`" -a \ "2" = "`get_property partition.system.verified`" ]; then - VERITY_WAS_ENABLED=true + restore() { + ${overlayfs_supported} || return 0 + echo "${GREEN}[ INFO ]${NORMAL} restoring verity" >&2 + inFastboot && + fastboot reboot && + adb_wait 2m + adb_root && + adb enable-verity && + adb_reboot && + adb_wait 2m + } fi echo "${GREEN}[ RUN ]${NORMAL} Testing kernel support for overlayfs" >&2 -overlayfs_supported=true; adb_wait || die "wait for device failed" adb_sh ls -d /sys/module/overlay /dev/null 2>/dev/null || adb_sh grep "nodev${TAB}overlay" /proc/filesystems /dev/null 2>/dev/null && @@ -478,7 +556,7 @@ if ${overlayfs_supported}; then echo "${ORANGE}[ WARNING ]${NORMAL} overlay module does not support override_creds" >&2 && false ) || - overlayfs_supported=false; + overlayfs_supported=false ;; *) echo "${GREEN}[ OK ]${NORMAL} overlay module uses callers creds" >&2 @@ -550,8 +628,8 @@ T=`adb_date` H=`adb disable-verity 2>&1` err=${?} L= -D="${H%?Now reboot your device for settings to take effect}" -if [ X"${D}" != X"${D##*using overlayfs}" ]; then +D="${H%?Now reboot your device for settings to take effect*}" +if [ X"${D}" != X"${D##*[Uu]sing overlayfs}" ]; then echo "${GREEN}[ OK ]${NORMAL} using overlayfs" >&2 fi if [ ${err} != 0 ]; then @@ -583,8 +661,8 @@ if [ X"${D}" != X"${H}" ]; then T=`adb_date` H=`adb disable-verity 2>&1` err=${?} - D="${H%?Now reboot your device for settings to take effect}" - if [ X"${D}" != X"${D##*using overlayfs}" ]; then + D="${H%?Now reboot your device for settings to take effect*}" + if [ X"${D}" != X"${D##*[Uu]sing overlayfs}" ]; then echo "${GREEN}[ OK ]${NORMAL} using overlayfs" >&2 fi if [ ${err} != 0 ]; then @@ -615,7 +693,11 @@ fi echo "${GREEN}[ RUN ]${NORMAL} remount" >&2 -adb remount || +D=`adb remount 2>&1` +ret=${?} +echo "${D}" +[ ${ret} != 0 ] || + [ X"${D}" = X"${D##*remount failed}" ] || ( [ -n "${L}" ] && echo "${L}" && false ) || die -t "${T}" "adb remount failed" D=`adb_sh df -k /dev/null; then + D=`echo / / + echo "${D}" | grep -v /dev/root` + fi + D=`echo "${D}" | cut -s -d' ' -f1 | sort -u` + bad_rw=false + for d in ${D}; do + if adb_sh tune2fs -l $d 2>&1 | + grep "Filesystem features:.*shared_blocks" >/dev/null; then + bad_rw=true + else + d=`adb_sh df -k ${D} &2 || echo "${GREEN}[ OK ]${NORMAL} overlay takeover in first stage init" >&2 fi @@ -749,7 +854,10 @@ adb_root && adb pull /system/lib/bootstrap/libc.so ${tempdir}/libc.so.fromdevice >/dev/null || die "pull libc.so from device" diff ${tempdir}/libc.so ${tempdir}/libc.so.fromdevice > /dev/null || die "libc.so differ" -rm -r ${tempdir} +rm -rf ${tempdir} +cleanup() { + true +} echo "${GREEN}[ OK ]${NORMAL} /system/lib/bootstrap/libc.so content remains after reboot" >&2 echo "${GREEN}[ RUN ]${NORMAL} flash vendor, confirm its content disappears" >&2 @@ -762,10 +870,14 @@ elif [ ! -s "${ANDROID_PRODUCT_OUT}/vendor.img" ]; then echo "${ORANGE}[ WARNING ]${NORMAL} vendor image missing, skipping" 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" else - adb reboot-fastboot && - fastboot_wait 2m && - fastboot flash vendor || + adb reboot-fastboot || + die "fastbootd not supported (wrong adb in path?)" + fastboot_wait 2m || + die "reboot into fastboot to flash vendor `usb_status`" + fastboot flash vendor || ( fastboot reboot && false) || die "fastboot flash vendor" fastboot_getvar is-userspace yes && @@ -804,7 +916,7 @@ else die "can not reboot out of fastboot" echo "${ORANGE}[ WARNING ]${NORMAL} adb after fastboot" adb_wait 2m || - die "did not reboot after flash" + die "did not reboot after flash `usb_status`" if ${overlayfs_needed}; then adb_root && D=`adb_sh df -k &1` err=${?} L= -D="${H%?Now reboot your device for settings to take effect}" +D="${H%?Now reboot your device for settings to take effect*}" if [ X"${H}" != X"${D}" ]; then echo "${ORANGE}[ WARNING ]${NORMAL} adb remount requires a reboot after partial flash (legacy avb)" L=`adb_logcat -b all -v nsec -t ${T} 2>&1` @@ -878,17 +990,18 @@ if [ -n "${scratch_partition}" ]; then adb reboot-fastboot || die "Reboot into fastbootd" + img=${TMPDIR}/adb-remount-test-${$}.img cleanup() { - rm /tmp/adb-remount-test.img + rm ${img} } - dd if=/dev/zero of=/tmp/adb-remount-test.img bs=4096 count=16 2>/dev/null && + dd if=/dev/zero of=${img} bs=4096 count=16 2>/dev/null && fastboot_wait 2m || - die "reboot into fastboot" - fastboot flash --force ${scratch_partition} /tmp/adb-remount-test.img + die "reboot into fastboot `usb_status`" + fastboot flash --force ${scratch_partition} ${img} err=${?} cleanup cleanup() { - : + true } fastboot reboot || die "can not reboot out of fastboot" @@ -900,14 +1013,32 @@ if [ -n "${scratch_partition}" ]; then T=`adb_date` D=`adb disable-verity 2>&1` err=${?} - adb remount || - die "remount failed" + if [ X"${D}" != "${D%?Now reboot your device for settings to take effect*}" ] + then + echo "${ORANGE}[ WARNING ]${NORMAL} adb disable-verity requires a reboot after partial flash" + adb_reboot && + adb_wait 2m && + adb_root || + die "failed to reboot" + T=`adb_date` + D="${D} +`adb disable-verity 2>&1`" + err=${?} + fi + echo "${D}" [ ${err} = 0 ] && [ X"${D}" = X"${D##*setup failed}" ] && - [ X"${D}" != X"${D##*using overlayfs}" ] && + [ X"${D}" != X"${D##*[Uu]sing overlayfs}" ] && echo "${GREEN}[ OK ]${NORMAL} ${scratch_partition} recreated" >&2 || die -t ${T} "setup for overlayfs" + D=`adb remount 2>&1` + err=${?} + echo "${D}" + [ ${err} != 0 ] || + [ X"${D}" = X"${D##*remount failed}" ] || + ( echo "${D}" && false ) || + die -t ${T} "remount failed" fi echo "${GREEN}[ RUN ]${NORMAL} test raw remount commands" >&2 @@ -924,12 +1055,12 @@ adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null || die "/vendor is not read-write" echo "${GREEN}[ OK ]${NORMAL} mount -o rw,remount command works" >&2 -if $VERITY_WAS_ENABLED && $overlayfs_supported; then - adb_root && - adb enable-verity && - adb_reboot && - adb_wait 2m || - die "failed to restore verity" >&2 -fi +restore +err=${?} +restore() { + true +} +[ ${err} = 0 ] || + die "failed to restore verity" >&2 echo "${GREEN}[ PASSED ]${NORMAL} adb remount" >&2