Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b1d78402 authored by Mark Salyzyn's avatar Mark Salyzyn Committed by Gerrit Code Review
Browse files

Merge changes I89826fc2,Ica0c14da,Icfbb799f,I233bbc7b,I30569a7c, ...

* changes:
  adb-remount-test: check devt and inode
  adb-remount-test: add an avc check
  adb-remount-test: parameterize fastboot_wait & adb_wait, increase timeout
  adb-remount-test: report wait duration
  adb-remount-test: check vendor image signature before using
  adb-remount-test: report usb user on unexpected connection
  adb-remount-test: wait-for-screen
parents 79b0682e 67788ef8
Loading
Loading
Loading
Loading
+239 −27
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ Conditions:
##  Helper Variables
##

EMPTY=""
SPACE=" "
# A _real_ embedded tab character
TAB="`echo | tr '\n' '\t'`"
@@ -50,6 +51,9 @@ print_time=false
start_time=`date +%s`
ACTIVE_SLOT=

ADB_WAIT=3m
FASTBOOT_WAIT=2m

##
##  Helper Functions
##
@@ -131,10 +135,30 @@ Returns: the logcat output" ]
adb_logcat() {
  echo "${RED}[     INFO ]${NORMAL} logcat ${@}" >&2 &&
  adb logcat "${@}" </dev/null |
    tr -d '\r' |
    grep -v 'logd    : logdr: UID=' |
    sed -e '${/------- beginning of kernel/d}' -e 's/^[0-1][0-9]-[0-3][0-9] //'
}

[ "USAGE: avc_check >/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 <prop>

Returns the property value" ]
@@ -173,6 +197,7 @@ adb_cat() {

Returns: true if the reboot command succeeded" ]
adb_reboot() {
  avc_check
  adb reboot remount-test </dev/null || true
  sleep 2
}
@@ -240,10 +265,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,9 +286,45 @@ 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}
}

[ "USAGE: adb_user > /dev/stdout

Returns: the adb daemon user" ]
adb_user() {
  adb_sh echo '${USER}' </dev/null
}

[ "USAGE: usb_status > stdout 2> stderr

Assumes referenced right after adb_wait or fastboot_wait failued.
@@ -276,7 +340,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`
@@ -366,17 +430,68 @@ 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

Returns: true if device in root state" ]
adb_root() {
  [ root != "`adb_sh echo '${USER}' </dev/null`" ] || return 0
  [ root != "`adb_user`" ] || return 0
  adb root >/dev/null </dev/null 2>/dev/null
  sleep 2
  adb_wait 2m &&
    [ root = "`adb_sh echo '${USER}' </dev/null`" ]
  adb_wait ${ADB_WAIT} &&
    [ root = "`adb_user`" ]
}

[ "USAGE: adb_unroot
@@ -385,11 +500,11 @@ NB: This can be flakey on devices due to USB state

Returns: true if device in un root state" ]
adb_unroot() {
  [ root = "`adb_sh echo '${USER}' </dev/null`" ] || return 0
  [ root = "`adb_user`" ] || return 0
  adb unroot >/dev/null </dev/null 2>/dev/null
  sleep 2
  adb_wait 2m &&
    [ root != "`adb_sh echo '${USER}' </dev/null`" ]
  adb_wait ${ADB_WAIT} &&
    [ root != "`adb_user`" ]
}

[ "USAGE: fastboot_getvar var expected >/dev/stderr
@@ -540,6 +655,30 @@ EXPECT_EQ() {
  return 0
}

[ "USAGE: EXPECT_NE <lval> <rval> [--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 <lval> <rval> [--warning [message]]

Exits if (regex) lval mismatches rval" ]
@@ -555,6 +694,21 @@ check_eq() {
    die "${@}"
}

[ "USAGE: check_ne <lval> <rval> [--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" ]
@@ -645,7 +799,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"
@@ -697,6 +851,8 @@ adb_sh ls -l /dev/block/by-name/ </dev/null 2>/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 \
@@ -705,19 +861,20 @@ 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

  avc_check
  adb_su remount -R system </dev/null || true
  sleep 2
  adb_wait 2m ||
  adb_wait ${ADB_WAIT} ||
    die "waiting for device after remount -R `usb_status`"
  if [ "orange" != "`get_property ro.boot.verifiedbootstate`" -o \
       "2" = "`get_property partition.system.verified`" ]; then
@@ -775,7 +932,7 @@ done
if ${reboot}; then
  echo "${ORANGE}[  WARNING ]${NORMAL} rebooting before test" >&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`"
@@ -840,7 +997,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`"
@@ -881,6 +1038,11 @@ fi

echo "${GREEN}[ RUN      ]${NORMAL} remount" >&2

# Feed log with selinux denials as baseline before overlays
adb_unroot
adb_sh find /system /vendor </dev/null >/dev/null 2>/dev/null
adb_root

D=`adb remount 2>&1`
ret=${?}
echo "${D}"
@@ -981,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 </dev/null`
VENDOR_DEVT=`adb_sh stat --format=%D /vendor/hello </dev/null`
SYSTEM_INO=`adb_sh stat --format=%i /system/hello </dev/null`
VENDOR_INO=`adb_sh stat --format=%i /vendor/hello </dev/null`
BASE_SYSTEM_DEVT=`adb_sh stat --format=%D /system/bin/stat </dev/null`
BASE_VENDOR_DEVT=`adb_sh stat --format=%D /vendor/bin/stat </dev/null`
check_eq "${SYSTEM_DEVT%[0-9a-fA-F][0-9a-fA-F]}" "${VENDOR_DEVT%[0-9a-fA-F][0-9a-fA-F]}" vendor and system devt
check_ne "${SYSTEM_INO}" "${VENDOR_INO}" vendor and system inode
if ${overlayfs_needed}; then
  check_ne "${SYSTEM_DEVT}" "${BASE_SYSTEM_DEVT}" system devt
  check_ne "${VENDOR_DEVT}" "${BASE_VENDOR_DEVT}" vendor devt
else
  check_eq "${SYSTEM_DEVT}" "${BASE_SYSTEM_DEVT}" system devt
  check_eq "${VENDOR_DEVT}" "${BASE_VENDOR_DEVT}" vendor devt
fi
check_ne "${BASE_SYSTEM_DEVT}" "${BASE_VENDOR_DEVT}" --warning system/vendor devt
[ -n "${SYSTEM_DEVT%[0-9a-fA-F][0-9a-fA-F]}" ] ||
  die "system devt ${SYSTEM_DEVT} is major 0"
[ -n "${VENDOR_DEVT%[0-9a-fA-F][0-9a-fA-F]}" ] ||
  die "vendor devt ${SYSTEM_DEVT} is major 0"

# Download libc.so, append some gargage, push back, and check if the file
# is updated.
@@ -1005,11 +1187,11 @@ fixup_from_recovery() {
  inRecovery || return 1
  echo "${ORANGE}[    ERROR ]${NORMAL} Device in recovery" >&2
  adb reboot </dev/null
  adb_wait 2m
  adb_wait ${ADB_WAIT}
}

adb_reboot &&
  adb_wait 2m ||
  adb_wait ${ADB_WAIT} ||
  fixup_from_recovery ||
  die "reboot after override content added failed `usb_status`"

@@ -1033,6 +1215,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 >/dev/null 2>/dev/null
fi
B="`adb_cat /system/hello`"
check_eq "${A}" "${B}" /system after reboot
@@ -1044,6 +1229,17 @@ B="`adb_cat /vendor/hello`"
check_eq "${A}" "${B}" vendor after reboot
echo "${GREEN}[       OK ]${NORMAL} /vendor content remains after reboot" >&2

check_eq "${SYSTEM_DEVT}" "`adb_sh stat --format=%D /system/hello </dev/null`" system devt after reboot
check_eq "${VENDOR_DEVT}" "`adb_sh stat --format=%D /vendor/hello </dev/null`" vendor devt after reboot
check_eq "${SYSTEM_INO}" "`adb_sh stat --format=%i /system/hello </dev/null`" system inode after reboot
check_eq "${VENDOR_INO}" "`adb_sh stat --format=%i /vendor/hello </dev/null`" vendor inode after reboot
check_eq "${BASE_SYSTEM_DEVT}" "`adb_sh stat --format=%D /system/bin/stat </dev/null`" base system devt after reboot
check_eq "${BASE_VENDOR_DEVT}" "`adb_sh stat --format=%D /vendor/bin/stat </dev/null`" base system devt after reboot
check_eq "${BASE_SYSTEM_DEVT}" "`adb_sh stat --format=%D /system/xbin/su </dev/null`" devt for su after reboot

# Feed log with selinux denials as a result of overlays
adb_sh find /system /vendor </dev/null >/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 ||
@@ -1073,10 +1269,17 @@ 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
  avc_check
  adb reboot fastboot </dev/null ||
    die "fastbootd not supported (wrong adb in path?)"
  any_wait 2m &&
  any_wait ${ADB_WAIT} &&
    inFastboot ||
    die "reboot into fastboot to flash vendor `usb_status` (bad bootloader?)"
  fastboot flash vendor ||
@@ -1117,7 +1320,7 @@ else
  fastboot reboot ||
    die "can not reboot out of fastboot"
  echo "${ORANGE}[  WARNING ]${NORMAL} adb after fastboot"
  adb_wait 2m ||
  adb_wait ${ADB_WAIT} ||
    fixup_from_recovery ||
    die "did not reboot after flash `usb_status`"
  if ${overlayfs_needed}; then
@@ -1150,8 +1353,15 @@ 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 </dev/null`" system devt after reboot
  check_eq "${SYSTEM_INO}" "`adb_sh stat --format=%i /system/hello </dev/null`" system inode after reboot
  check_eq "${BASE_SYSTEM_DEVT}" "`adb_sh stat --format=%D /system/bin/stat </dev/null`" base system devt after reboot
  check_eq "${BASE_SYSTEM_DEVT}" "`adb_sh stat --format=%D /system/xbin/su </dev/null`" devt for su after reboot

fi

wait_for_screen
echo "${GREEN}[ RUN      ]${NORMAL} remove test content (cleanup)" >&2

T=`adb_date`
@@ -1163,7 +1373,7 @@ 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`
  adb_reboot &&
    adb_wait 2m &&
    adb_wait ${ADB_WAIT} &&
    adb_root ||
    die "failed to reboot"
  T=`adb_date`
@@ -1185,6 +1395,7 @@ if [ -n "${scratch_partition}" ]; then

  echo "${GREEN}[ RUN      ]${NORMAL} test fastboot flash to ${scratch_partition} recovery" >&2

  avc_check
  adb reboot fastboot </dev/null ||
    die "Reboot into fastbootd"
  img=${TMPDIR}/adb-remount-test-${$}.img
@@ -1192,7 +1403,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=${?}
@@ -1204,7 +1415,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`
@@ -1214,7 +1425,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`
@@ -1252,12 +1463,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 </dev/null &&
@@ -1270,7 +1481,7 @@ echo "${GREEN}[ OK ]${NORMAL} mount -o rw,remount command works" >&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 &&
@@ -1291,7 +1502,7 @@ for d in ${OVERLAYFS_BACKING}; do
    die "/${d}/overlay wipe"
done
adb_reboot &&
  adb_wait 2m ||
  adb_wait ${ADB_WAIT} ||
  fixup_from_fastboot ||
  die "lost device after reboot after wipe `usb_status`"
adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null &&
@@ -1309,9 +1520,10 @@ err=${?}

if [ ${err} = 0 ] && ${overlayfs_supported}; then
  echo "${GREEN}[ RUN      ]${NORMAL} test 'adb remount -R'" >&2
  avc_check
  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