• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#! /bin/bash
2#
3# Divided into four section:
4#
5##  USAGE
6##  Helper Variables
7##  Helper Functions
8##  MAINLINE
9
10##
11##  USAGE
12##
13
14USAGE="USAGE: `basename ${0}` [--help] [--serial <SerialNumber>] [options]
15
16adb remount tests
17
18-c --color                     Dress output with highlighting colors
19-h --help                      This help
20-D --no-wait-screen            Do not wait for display screen to settle
21-t --print-time                Report the test duration
22-s --serial                    Specify device (must if multiple are present)"
23if [ -n "`which timeout`" ]; then
24  USAGE="${USAGE}
25-a --wait-adb <duration>       adb wait timeout
26-f --wait-fastboot <duration>  fastboot wait timeout"
27fi
28USAGE="${USAGE}
29
30Conditions:
31 - Must be a userdebug build.
32 - Must be in adb mode.
33 - Also tests overlayfs
34  - Kernel must have overlayfs enabled and patched to support override_creds.
35  - Must have either erofs, squashfs, ext4-dedupe or full partitions.
36  - Minimum expectation system and vender are overlayfs covered partitions.
37"
38
39##
40##  Helper Variables
41##
42
43EMPTY=""
44SPACE=" "
45# Line up wrap to [  XXXXXXX ] messages.
46INDENT="             "
47# A _real_ embedded tab character
48TAB="`echo | tr '\n' '\t'`"
49# A _real_ embedded escape character
50ESCAPE="`echo | tr '\n' '\033'`"
51# A _real_ embedded carriage return character
52CR="`echo | tr '\n' '\r'`"
53GREEN="${ESCAPE}[32m"
54RED="${ESCAPE}[31m"
55YELLOW="${ESCAPE}[33m"
56BLUE="${ESCAPE}[34m"
57NORMAL="${ESCAPE}[0m"
58TMPDIR=${TMPDIR:-/tmp}
59print_time=false
60start_time=`date +%s`
61ACTIVE_SLOT=
62
63ADB_WAIT=4m
64FASTBOOT_WAIT=2m
65screen_wait=true
66
67##
68##  Helper Functions
69##
70
71[ "USAGE: inFastboot
72
73Returns: true if device is in fastboot mode" ]
74inFastboot() {
75  fastboot devices |
76    if [ -n "${ANDROID_SERIAL}" ]; then
77      grep "^${ANDROID_SERIAL}[${SPACE}${TAB}]" > /dev/null
78    else
79      wc -l | grep "^[${SPACE}${TAB}]*1\$" >/dev/null
80    fi
81}
82
83[ "USAGE: inAdb
84
85Returns: true if device is in adb mode" ]
86inAdb() {
87  adb devices |
88    grep -v -e 'List of devices attached' -e '^$' -e "[${SPACE}${TAB}]recovery\$" |
89    if [ -n "${ANDROID_SERIAL}" ]; then
90      grep "^${ANDROID_SERIAL}[${SPACE}${TAB}]" > /dev/null
91    else
92      wc -l | grep "^[${SPACE}${TAB}]*1\$" >/dev/null
93    fi
94}
95
96[ "USAGE: inRecovery
97
98Returns: true if device is in recovery mode" ]
99inRecovery() {
100  local list="`adb devices |
101              grep -v -e 'List of devices attached' -e '^$'`"
102  if [ -n "${ANDROID_SERIAL}" ]; then
103    echo "${list}" |
104      grep "^${ANDROID_SERIAL}[${SPACE}${TAB}][${SPACE}${TAB}]*recovery\$" >/dev/null
105    return ${?}
106  fi
107  if echo "${list}" | wc -l | grep "^[${SPACE}${TAB}]*1\$" >/dev/null; then
108    echo "${list}" |
109      grep "[${SPACE}${TAB}]recovery\$" >/dev/null
110    return ${?}
111  fi
112  false
113}
114
115[ "USAGE: adb_sh <commands> </dev/stdin >/dev/stdout 2>/dev/stderr
116
117Returns: true if the command succeeded" ]
118adb_sh() {
119  local args=
120  for i in "${@}"; do
121    [ -z "${args}" ] || args="${args} "
122    if [ X"${i}" != X"${i#\'}" ]; then
123      args="${args}${i}"
124    elif [ X"${i}" != X"${i#* }" ]; then
125      args="${args}'${i}'"
126    elif [ X"${i}" != X"${i#*${TAB}}" ]; then
127      args="${args}'${i}'"
128    else
129      args="${args}${i}"
130    fi
131  done
132  adb shell "${args}"
133}
134
135[ "USAGE: adb_date >/dev/stdout
136
137Returns: report device epoch time (suitable for logcat -t)" ]
138adb_date() {
139  adb_sh date +%s.%N </dev/null
140}
141
142[ "USAGE: adb_logcat [arguments] >/dev/stdout
143
144Returns: the logcat output" ]
145adb_logcat() {
146  echo "${RED}[     INFO ]${NORMAL} logcat ${@}" >&2 &&
147  adb logcat "${@}" </dev/null |
148    tr -d '\r' |
149    grep -v 'logd    : logdr: UID=' |
150    sed -e '${ /------- beginning of kernel/d }' -e 's/^[0-1][0-9]-[0-3][0-9] //'
151}
152
153[ "USAGE: avc_check >/dev/stderr
154
155Returns: worrisome avc violations" ]
156avc_check() {
157  if ! ${overlayfs_supported:-false}; then
158    return
159  fi
160  local L=`adb_logcat -b all -v brief -d \
161                      -e 'context=u:object_r:unlabeled:s0' 2>/dev/null |
162             sed -n 's/.*avc: //p' |
163             sort -u`
164  if [ -z "${L}" ]; then
165    return
166  fi
167  echo "${YELLOW}[  WARNING ]${NORMAL} unlabeled sepolicy violations:" >&2
168  echo "${L}" | sed "s/^/${INDENT}/" >&2
169}
170
171[ "USAGE: get_property <prop>
172
173Returns the property value" ]
174get_property() {
175  adb_sh getprop ${1} </dev/null
176}
177
178[ "USAGE: isDebuggable
179
180Returns: true if device is (likely) a debug build" ]
181isDebuggable() {
182  if inAdb && [ 1 != "`get_property ro.debuggable`" ]; then
183    false
184  fi
185}
186
187[ "USAGE: adb_su <commands> </dev/stdin >/dev/stdout 2>/dev/stderr
188
189Returns: true if the command running as root succeeded" ]
190adb_su() {
191  adb_sh su root "${@}"
192}
193
194[ "USAGE: adb_cat <file> >stdout
195
196Returns: content of file to stdout with carriage returns skipped,
197         true if the file exists" ]
198adb_cat() {
199    local OUTPUT="`adb_sh cat ${1} </dev/null 2>&1`"
200    local ret=${?}
201    echo "${OUTPUT}" | tr -d '\r'
202    return ${ret}
203}
204
205[ "USAGE: adb_ls <dirfile> >stdout
206
207Returns: filename or directoru content to stdout with carriage returns skipped,
208         true if the ls had no errors" ]
209adb_ls() {
210    local OUTPUT="`adb_sh ls ${1} </dev/null 2>/dev/null`"
211    local ret=${?}
212    echo "${OUTPUT}" | tr -d '\r'
213    return ${ret}
214}
215
216[ "USAGE: adb_test <expression>
217
218Returns: exit status of the test expression" ]
219adb_test() {
220  adb_sh test "${@}" </dev/null
221}
222
223[ "USAGE: adb_reboot
224
225Returns: true if the reboot command succeeded" ]
226adb_reboot() {
227  avc_check
228  adb reboot remount-test </dev/null || true
229  sleep 2
230}
231
232[ "USAGE: format_duration [<seconds>|<seconds>s|<minutes>m|<hours>h|<days>d]
233
234human readable output whole seconds, whole minutes or mm:ss" ]
235format_duration() {
236  if [ -z "${1}" ]; then
237    echo unknown
238    return
239  fi
240  local duration="${1}"
241  if [ X"${duration}" != X"${duration%s}" ]; then
242    duration=${duration%s}
243  elif [ X"${duration}" != X"${duration%m}" ]; then
244    duration=`expr ${duration%m} \* 60`
245  elif [ X"${duration}" != X"${duration%h}" ]; then
246    duration=`expr ${duration%h} \* 3600`
247  elif [ X"${duration}" != X"${duration%d}" ]; then
248    duration=`expr ${duration%d} \* 86400`
249  fi
250  local seconds=`expr ${duration} % 60`
251  local minutes=`expr \( ${duration} / 60 \) % 60`
252  local hours=`expr ${duration} / 3600`
253  if [ 0 -eq ${minutes} -a 0 -eq ${hours} ]; then
254    if [ 1 -eq ${duration} ]; then
255      echo 1 second
256      return
257    fi
258    echo ${duration} seconds
259    return
260  elif [ 60 -eq ${duration} ]; then
261    echo 1 minute
262    return
263  elif [ 0 -eq ${seconds} -a 0 -eq ${hours} ]; then
264    echo ${minutes} minutes
265    return
266  fi
267  if [ 0 -eq ${hours} ]; then
268    echo ${minutes}:`expr ${seconds} / 10``expr ${seconds} % 10`
269    return
270  fi
271  echo ${hours}:`expr ${minutes} / 10``expr ${minutes} % 10`:`expr ${seconds} / 10``expr ${seconds} % 10`
272}
273
274[ "USAGE: USB_DEVICE=\`usb_devnum [--next]\`
275
276USB_DEVICE contains cache. Update if system changes.
277
278Returns: the devnum for the USB_SERIAL device" ]
279usb_devnum() {
280  if [ -n "${USB_SERIAL}" ]; then
281    local usb_device=`cat ${USB_SERIAL%/serial}/devnum 2>/dev/null | tr -d ' \t\r\n'`
282    if [ -n "${usb_device}" ]; then
283      USB_DEVICE=dev${usb_device}
284    elif [ -n "${USB_DEVICE}" -a "${1}" ]; then
285      USB_DEVICE=dev`expr ${USB_DEVICE#dev} + 1`
286    fi
287    echo "${USB_DEVICE}"
288  fi
289}
290
291[ "USAGE: adb_wait [timeout]
292
293Returns: waits until the device has returned for adb or optional timeout" ]
294adb_wait() {
295  local start=`date +%s`
296  local duration=
297  local ret
298  if [ -n "${1}" -a -n "`which timeout`" ]; then
299    USB_DEVICE=`usb_devnum --next`
300    duration=`format_duration ${1}`
301    echo -n ". . . waiting ${duration}" ${ANDROID_SERIAL} ${USB_ADDRESS} ${USB_DEVICE} "${CR}"
302    timeout --preserve-status --signal=KILL ${1} adb wait-for-device 2>/dev/null
303    ret=${?}
304    echo -n "                                                                             ${CR}"
305  else
306    adb wait-for-device
307    ret=${?}
308  fi
309  USB_DEVICE=`usb_devnum`
310  if [ 0 = ${ret} -a -n "${ACTIVE_SLOT}" ]; then
311    local active_slot=`get_active_slot`
312    if [ X"${ACTIVE_SLOT}" != X"${active_slot}" ]; then
313      echo "${YELLOW}[  WARNING ]${NORMAL} Active slot changed from ${ACTIVE_SLOT} to ${active_slot}" >&2
314    fi
315  fi
316  local end=`date +%s`
317  local diff_time=`expr ${end} - ${start}`
318  local _print_time=${print_time}
319  if [ ${diff_time} -lt 15 ]; then
320    _print_time=false
321  fi
322  diff_time=`format_duration ${diff_time}`
323  if [ "${diff_time}" = "${duration}" ]; then
324    _print_time=false
325  fi
326
327  local reason=
328  if inAdb; then
329    reason=`get_property ro.boot.bootreason`
330  fi
331  case ${reason} in
332    reboot*)
333      reason=
334      ;;
335    ${EMPTY})
336      ;;
337    *)
338      reason=" for boot reason ${reason}"
339      ;;
340  esac
341  if ${_print_time} || [ -n "${reason}" ]; then
342    echo "${BLUE}[     INFO ]${NORMAL} adb wait duration ${diff_time}${reason}"
343  fi >&2
344
345  return ${ret}
346}
347
348[ "USAGE: adb_user > /dev/stdout
349
350Returns: the adb daemon user" ]
351adb_user() {
352  adb_sh echo '${USER}' </dev/null
353}
354
355[ "USAGE: usb_status > stdout 2> stderr
356
357Assumes referenced right after adb_wait or fastboot_wait failued.
358If wait failed, check if device is in adb, recovery or fastboot mode
359and report status strings like  \"(USB stack borken?)\",
360\"(In fastboot mode)\", \"(In recovery mode)\" or \"(in adb mode)\".
361Additional diagnostics may be provided to the stderr output.
362
363Returns: USB status string" ]
364usb_status() {
365  if inFastboot; then
366    echo "(In fastboot mode)"
367  elif inRecovery; then
368    echo "(In recovery mode)"
369  elif inAdb; then
370    echo "(In adb mode `adb_user`)"
371  else
372    echo "(USB stack borken for ${USB_ADDRESS})"
373    if [ -n "`which usb_devnum`" ]; then
374      USB_DEVICE=`usb_devnum`
375      if [ -n "`which lsusb`" ]; then
376        if [ -n "${USB_DEVICE}" ]; then
377          echo "# lsusb -v -s ${USB_DEVICE#dev}"
378          local D=`lsusb -v -s ${USB_DEVICE#dev} 2>&1`
379          if [ -n "${D}" ]; then
380            echo "${D}"
381          else
382            lsusb -v
383          fi
384        else
385          echo "# lsusb -v (expected device missing)"
386          lsusb -v
387        fi
388      fi
389    fi >&2
390  fi
391}
392
393[ "USAGE: fastboot_wait [timeout]
394
395Returns: waits until the device has returned for fastboot or optional timeout" ]
396fastboot_wait() {
397  local ret
398  # fastboot has no wait-for-device, but it does an automatic
399  # wait and requires (even a nonsensical) command to do so.
400  if [ -n "${1}" -a -n "`which timeout`" ]; then
401    USB_DEVICE=`usb_devnum --next`
402    echo -n ". . . waiting `format_duration ${1}`" ${ANDROID_SERIAL} ${USB_ADDRESS} ${USB_DEVICE} "${CR}"
403    timeout --preserve-status --signal=KILL ${1} fastboot wait-for-device >/dev/null 2>/dev/null
404    ret=${?}
405    echo -n "                                                                             ${CR}"
406    ( exit ${ret} )
407  else
408    fastboot wait-for-device >/dev/null 2>/dev/null
409  fi ||
410    inFastboot
411  ret=${?}
412  USB_DEVICE=`usb_devnum`
413  if [ 0 = ${ret} -a -n "${ACTIVE_SLOT}" ]; then
414    local active_slot=`get_active_slot`
415    if [ X"${ACTIVE_SLOT}" != X"${active_slot}" ]; then
416      echo "${YELLOW}[  WARNING ]${NORMAL} Active slot changed from ${ACTIVE_SLOT} to ${active_slot}"
417    fi >&2
418  fi
419  return ${ret}
420}
421
422[ "USAGE: recovery_wait [timeout]
423
424Returns: waits until the device has returned for recovery or optional timeout" ]
425recovery_wait() {
426  local ret
427  if [ -n "${1}" -a -n "`which timeout`" ]; then
428    USB_DEVICE=`usb_devnum --next`
429    echo -n ". . . waiting `format_duration ${1}`" ${ANDROID_SERIAL} ${USB_ADDRESS} ${USB_DEVICE} "${CR}"
430    timeout --preserve-status --signal=KILL ${1} adb wait-for-recovery 2>/dev/null
431    ret=${?}
432    echo -n "                                                                             ${CR}"
433  else
434    adb wait-for-recovery
435    ret=${?}
436  fi
437  USB_DEVICE=`usb_devnum`
438  if [ 0 = ${ret} -a -n "${ACTIVE_SLOT}" ]; then
439    local active_slot=`get_active_slot`
440    if [ X"${ACTIVE_SLOT}" != X"${active_slot}" ]; then
441      echo "${YELLOW}[  WARNING ]${NORMAL} Active slot changed from ${ACTIVE_SLOT} to ${active_slot}"
442    fi >&2
443  fi
444  return ${ret}
445}
446
447[ "any_wait [timeout]
448
449Returns: waits until a device has returned or optional timeout" ]
450any_wait() {
451  (
452    adb_wait ${1} &
453    adb_pid=${!}
454    fastboot_wait ${1} &
455    fastboot_pid=${!}
456    recovery_wait ${1} &
457    recovery_pid=${!}
458    wait -n
459    kill "${adb_pid}" "${fastboot_pid}" "${recovery_pid}"
460  ) >/dev/null 2>/dev/null
461  inFastboot || inAdb || inRecovery
462}
463
464wait_for_screen_timeout=900
465[ "USAGE: wait_for_screen [-n] [TIMEOUT]
466
467-n - echo newline at exit
468TIMEOUT - default `format_duration ${wait_for_screen_timeout}`" ]
469wait_for_screen() {
470  if ! ${screen_wait}; then
471    adb_wait
472    return
473  fi
474  exit_function=true
475  if [ X"-n" = X"${1}" ]; then
476    exit_function=echo
477    shift
478  fi
479  timeout=${wait_for_screen_timeout}
480  if [ ${#} -gt 0 ]; then
481    timeout=${1}
482    shift
483  fi
484  counter=0
485  while true; do
486    if inFastboot; then
487      fastboot reboot
488    elif inAdb; then
489      if [ 0 != ${counter} ]; then
490        adb_wait
491      fi
492      if [ "1" = "`get_property sys.boot_completed`" ]; then
493        sleep 1
494        break
495      fi
496    fi
497    counter=`expr ${counter} + 1`
498    if [ ${counter} -gt ${timeout} ]; then
499      ${exit_function}
500      echo "ERROR: wait_for_screen() timed out (`format_duration ${timeout}`)" >&2
501      return 1
502    fi
503    sleep 1
504  done
505  ${exit_function}
506}
507
508[ "USAGE: adb_root
509
510NB: This can be flakey on devices due to USB state
511
512Returns: true if device in root state" ]
513adb_root() {
514  [ root != "`adb_user`" ] || return 0
515  adb root >/dev/null </dev/null 2>/dev/null
516  sleep 2
517  adb_wait ${ADB_WAIT} &&
518    [ root = "`adb_user`" ]
519}
520
521[ "USAGE: adb_unroot
522
523NB: This can be flakey on devices due to USB state
524
525Returns: true if device in un root state" ]
526adb_unroot() {
527  [ root = "`adb_user`" ] || return 0
528  adb unroot >/dev/null </dev/null 2>/dev/null
529  sleep 2
530  adb_wait ${ADB_WAIT} &&
531    [ root != "`adb_user`" ]
532}
533
534[ "USAGE: fastboot_getvar var expected >/dev/stderr
535
536Returns: true if var output matches expected" ]
537fastboot_getvar() {
538  local O=`fastboot getvar ${1} 2>&1`
539  local ret=${?}
540  O="${O#< waiting for * >?}"
541  O="${O%%?Finished. Total time: *}"
542  if [ 0 -ne ${ret} ]; then
543    echo ${O} >&2
544    false
545    return
546  fi
547  if [ "${O}" != "${O#*FAILED}" ]; then
548    O="${1}: <empty>"
549  fi
550  if [ -n "${2}" -a "${1}: ${2}" != "${O}" ]; then
551    echo "${2} != ${O}"
552    false
553    return
554  fi >&2
555  echo ${O} >&2
556}
557
558[ "USAGE: get_active_slot >/dev/stdout
559
560Returns: with a or b string reporting active slot" ]
561get_active_slot() {
562  if inAdb || inRecovery; then
563    get_property ro.boot.slot_suffix | tr -d _
564  elif inFastboot; then
565    fastboot_getvar current-slot 2>&1 | sed -n 's/current-slot: //p'
566  else
567    false
568  fi
569}
570
571[ "USAGE: restore
572
573Do nothing: should be redefined when necessary.  Called after cleanup.
574
575Returns: reverses configurations" ]
576restore() {
577  true
578}
579
580[ "USAGE: cleanup
581
582Do nothing: should be redefined when necessary
583
584Returns: cleans up any latent resources" ]
585cleanup() {
586  true
587}
588
589[ "USAGE: test_duration >/dev/stderr
590
591Prints the duration of the test
592
593Returns: reports duration" ]
594test_duration() {
595  if ${print_time}; then
596    echo "${BLUE}[     INFO ]${NORMAL} end `date`"
597    [ -n "${start_time}" ] || return
598    end_time=`date +%s`
599    local diff_time=`expr ${end_time} - ${start_time}`
600    echo "${BLUE}[     INFO ]${NORMAL} duration `format_duration ${diff_time}`"
601  fi >&2
602}
603
604[ "USAGE: die [-d|-t <epoch>] [message] >/dev/stderr
605
606If -d, or -t <epoch> argument is supplied, dump logcat.
607
608Returns: exit failure, report status" ]
609die() {
610  if [ X"-d" = X"${1}" ]; then
611    adb_logcat -b all -v nsec -d
612    shift
613  elif [ X"-t" = X"${1}" ]; then
614    if [ -n "${2}" ]; then
615      adb_logcat -b all -v nsec -t ${2}
616    else
617      adb_logcat -b all -v nsec -d
618    fi
619    shift 2
620  fi >&2
621  echo "${RED}[  FAILED  ]${NORMAL} ${@}" >&2
622  cleanup
623  restore
624  test_duration
625  exit 1
626}
627
628[ "USAGE: EXPECT_EQ <lval> <rval> [--warning [message]]
629
630Returns true if (regex) lval matches rval" ]
631EXPECT_EQ() {
632  local lval="${1}"
633  local rval="${2}"
634  shift 2
635  local error=1
636  local prefix="${RED}[    ERROR ]${NORMAL}"
637  if [ X"${1}" = X"--warning" ]; then
638      prefix="${RED}[  WARNING ]${NORMAL}"
639      error=0
640      shift 1
641  fi
642  if ! ( echo X"${rval}" | grep '^X'"${lval}"'$' >/dev/null 2>/dev/null ); then
643    if [ `echo ${lval}${rval}${*} | wc -c` -gt 50 -o "${rval}" != "${rval%
644*}" ]; then
645      echo "${prefix} expected \"${lval}\""
646      echo "${prefix} got \"${rval}\"" |
647        sed ": again
648             N
649             s/\(\n\)\([^ ]\)/\1${INDENT}\2/
650             t again"
651      if [ -n "${*}" ] ; then
652        echo "${prefix} ${*}"
653      fi
654    else
655      echo "${prefix} expected \"${lval}\" got \"${rval}\" ${*}"
656    fi >&2
657    return ${error}
658  fi
659  if [ -n "${*}" ] ; then
660    prefix="${GREEN}[     INFO ]${NORMAL}"
661    if [ X"${lval}" != X"${rval}" ]; then  # we were supplied a regex?
662      if [ `echo ${lval}${rval}${*} | wc -c` -gt 60 -o "${rval}" != "${rval% *}" ]; then
663        echo "${prefix} ok \"${lval}\""
664        echo "       = \"${rval}\"" |
665          sed ": again
666               N
667               s/\(\n\)\([^ ]\)/\1${INDENT}\2/
668               t again"
669        if [ -n "${*}" ] ; then
670          echo "${prefix} ${*}"
671        fi
672      else
673        echo "${prefix} ok \"${lval}\" = \"${rval}\" ${*}"
674      fi
675    else
676      echo "${prefix} ok \"${lval}\" ${*}"
677    fi >&2
678  fi
679  return 0
680}
681
682[ "USAGE: EXPECT_NE <lval> <rval> [--warning [message]]
683
684Returns true if lval matches rval" ]
685EXPECT_NE() {
686  local lval="${1}"
687  local rval="${2}"
688  shift 2
689  local error=1
690  local prefix="${RED}[    ERROR ]${NORMAL}"
691  if [ X"${1}" = X"--warning" ]; then
692      prefix="${RED}[  WARNING ]${NORMAL}"
693      error=0
694      shift 1
695  fi
696  if [ X"${rval}" = X"${lval}" ]; then
697    echo "${prefix} did not expect \"${lval}\" ${*}" >&2
698    return ${error}
699  fi
700  if [ -n "${*}" ] ; then
701    echo "${prefix} ok \"${lval}\" not \"${rval}\" ${*}" >&2
702  fi
703  return 0
704}
705
706[ "USAGE: check_eq <lval> <rval> [--warning [message]]
707
708Exits if (regex) lval mismatches rval" ]
709check_eq() {
710  local lval="${1}"
711  local rval="${2}"
712  shift 2
713  if [ X"${1}" = X"--warning" ]; then
714      EXPECT_EQ "${lval}" "${rval}" ${*}
715      return
716  fi
717  if ! EXPECT_EQ "${lval}" "${rval}"; then
718    die "${@}"
719  fi
720}
721
722[ "USAGE: check_ne <lval> <rval> [--warning [message]]
723
724Exits if lval matches rval" ]
725check_ne() {
726  local lval="${1}"
727  local rval="${2}"
728  shift 2
729  if [ X"${1}" = X"--warning" ]; then
730      EXPECT_NE "${lval}" "${rval}" ${*}
731      return
732  fi
733  if ! EXPECT_NE "${lval}" "${rval}"; then
734    die "${@}"
735  fi
736}
737
738[ "USAGE: join_with <delimiter> <strings>
739
740Joins strings with delimiter" ]
741join_with() {
742  if [ "${#}" -lt 2 ]; then
743    echo
744    return
745  fi
746  local delimiter="${1}"
747  local result="${2}"
748  shift 2
749  for element in "${@}"; do
750    result+="${delimiter}${element}"
751  done
752  echo "${result}"
753}
754
755[ "USAGE: skip_administrative_mounts [data] < /proc/mounts
756
757Filters out all administrative (eg: sysfs) mounts uninteresting to the test" ]
758skip_administrative_mounts() {
759  local exclude_filesystems=(
760    "overlay" "tmpfs" "none" "sysfs" "proc" "selinuxfs" "debugfs" "bpf"
761    "binfmt_misc" "cg2_bpf" "pstore" "tracefs" "adb" "mtp" "ptp" "devpts"
762    "ramdumpfs" "binder" "securityfs" "functionfs" "rootfs"
763  )
764  local exclude_devices=(
765    "\/sys\/kernel\/debug" "\/data\/media" "\/dev\/block\/loop[0-9]*"
766    "${exclude_filesystems[@]}"
767  )
768  local exclude_mount_points=(
769    "\/cache" "\/mnt\/scratch" "\/mnt\/vendor\/persist" "\/persist"
770    "\/metadata"
771  )
772  if [ "data" = "${1}" ]; then
773    exclude_mount_points+=("\/data")
774  fi
775  awk '$1 !~ /^('"$(join_with "|" "${exclude_devices[@]}")"')$/ &&
776      $2 !~ /^('"$(join_with "|" "${exclude_mount_points[@]}")"')$/ &&
777      $3 !~ /^('"$(join_with "|" "${exclude_filesystems[@]}")"')$/'
778}
779
780[ "USAGE: skip_unrelated_mounts < /proc/mounts
781
782or output from df
783
784Filters out all apex and vendor override administrative overlay mounts
785uninteresting to the test" ]
786skip_unrelated_mounts() {
787    grep -v "^overlay.* /\(apex\|bionic\|system\|vendor\)/[^ ]" |
788      grep -v "[%] /\(data_mirror\|apex\|bionic\|system\|vendor\)/[^ ][^ ]*$"
789}
790
791##
792##  MAINLINE
793##
794
795HOSTOS=`uname`
796GETOPTS="--alternative --unquoted
797         --longoptions help,serial:,colour,color,no-colour,no-color
798         --longoptions wait-adb:,wait-fastboot:
799         --longoptions wait-screen,wait-display
800         --longoptions no-wait-screen,no-wait-display
801         --longoptions gtest_print_time,print-time
802         --"
803if [ "Darwin" = "${HOSTOS}" ]; then
804  GETOPTS=
805  USAGE="`echo \"${USAGE}\" |
806            sed 's/--color/       /g
807                 1s/--help/-h/
808                 s/--help/      /g
809                 s/--no-wait-screen/                /g
810                 s/--print-time/            /g
811                 1s/--serial/-s/
812                 s/--serial/        /g
813                 s/--wait-adb/          /g
814                 s/--wait-fastboot/               /g'`"
815fi
816OPTIONS=`getopt ${GETOPTS} "?a:cCdDf:hs:t" ${*}` ||
817  ( echo "${USAGE}" >&2 ; false ) ||
818  die "getopt failure"
819set -- ${OPTIONS}
820
821color=false
822while [ ${#} -gt 0 ]; do
823  case ${1} in
824    -h | --help | -\?)
825      echo "${USAGE}" >&2
826      exit 0
827      ;;
828    -s | --serial)
829      export ANDROID_SERIAL=${2}
830      shift
831      ;;
832    -c | --color | --colour)
833      color=true
834      ;;
835    -C | --no-color | --no-colour)
836      color=false
837      ;;
838    -D | --no-wait-display | --no-wait-screen)
839      screen_wait=false
840      ;;
841    -d | --wait-display | --wait-screen)
842      screen_wait=true
843      ;;
844    -t | --print-time | --gtest_print_time)
845      print_time=true
846      ;;
847    -a | --wait-adb)
848      ADB_WAIT=${2}
849      shift
850      ;;
851    -f | --wait-fastboot)
852      FASTBOOT_WAIT=${2}
853      shift
854      ;;
855    --)
856      shift
857      break
858      ;;
859    -*)
860      echo "${USAGE}" >&2
861      die "${0}: error unknown option ${1}"
862      ;;
863    *)
864      break
865      ;;
866  esac
867  shift
868done
869if ! ${color}; then
870  GREEN=""
871  RED=""
872  YELLOW=""
873  BLUE=""
874  NORMAL=""
875fi
876
877# Set an ERR trap handler to report any unhandled error
878trap 'die "line ${LINENO}: unhandled error"' ERR
879
880if ${print_time}; then
881  echo "${BLUE}[     INFO ]${NORMAL}" start `date` >&2
882fi
883
884inFastboot && die "device in fastboot mode"
885inRecovery && die "device in recovery mode"
886if ! inAdb; then
887  echo "${YELLOW}[  WARNING ]${NORMAL} device not in adb mode" >&2
888  adb_wait ${ADB_WAIT}
889fi
890inAdb || die "specified device not in adb mode"
891isDebuggable || die "device not a debug build"
892enforcing=true
893if ! adb_su getenforce </dev/null | grep 'Enforcing' >/dev/null; then
894  echo "${YELLOW}[  WARNING ]${NORMAL} device does not have sepolicy in enforcing mode" >&2
895  enforcing=false
896fi
897
898# Do something.
899
900# Collect characteristics of the device and report.
901
902D=`get_property ro.serialno`
903[ -n "${D}" ] || D=`get_property ro.boot.serialno`
904[ -z "${D}" -o -n "${ANDROID_SERIAL}" ] || ANDROID_SERIAL=${D}
905USB_SERIAL=
906if [ -n "${ANDROID_SERIAL}" -a "Darwin" != "${HOSTOS}" ]; then
907  USB_SERIAL="`find /sys/devices -name serial | grep usb || true`"
908  if [ -n "${USB_SERIAL}" ]; then
909    USB_SERIAL=`echo "${USB_SERIAL}" |
910                  xargs grep -l ${ANDROID_SERIAL} || true`
911  fi
912fi
913USB_ADDRESS=
914if [ -n "${USB_SERIAL}" ]; then
915  USB_ADDRESS=${USB_SERIAL%/serial}
916  USB_ADDRESS=usb${USB_ADDRESS##*/}
917fi
918[ -z "${ANDROID_SERIAL}${USB_ADDRESS}" ] ||
919  USB_DEVICE=`usb_devnum`
920  echo "${BLUE}[     INFO ]${NORMAL}" ${ANDROID_SERIAL} ${USB_ADDRESS} ${USB_DEVICE} >&2
921BUILD_DESCRIPTION=`get_property ro.build.description`
922[ -z "${BUILD_DESCRIPTION}" ] ||
923  echo "${BLUE}[     INFO ]${NORMAL} ${BUILD_DESCRIPTION}" >&2
924KERNEL_VERSION="`adb_su cat /proc/version </dev/null 2>/dev/null`"
925[ -z "${KERNEL_VERSION}" ] ||
926  echo "${BLUE}[     INFO ]${NORMAL} ${KERNEL_VERSION}" >&2
927ACTIVE_SLOT=`get_active_slot`
928[ -z "${ACTIVE_SLOT}" ] ||
929  echo "${BLUE}[     INFO ]${NORMAL} active slot is ${ACTIVE_SLOT}" >&2
930
931# Acquire list of system partitions
932
933# KISS (assume system partition mount point is "/<partition name>")
934PARTITIONS=`adb_su cat /vendor/etc/fstab* </dev/null |
935              grep -v "^[#${SPACE}${TAB}]" |
936              skip_administrative_mounts |
937              awk '$1 ~ /^[^\/]+$/ && "/"$1 == $2 && $4 ~ /(^|,)ro(,|$)/ { print $1 }' |
938              sort -u |
939              tr '\n' ' '`
940PARTITIONS="${PARTITIONS:-system vendor}"
941# KISS (we do not support sub-mounts for system partitions currently)
942MOUNTS="`for i in ${PARTITIONS}; do
943           echo /${i}
944         done |
945         tr '\n' ' '`"
946echo "${BLUE}[     INFO ]${NORMAL} System Partitions list: ${PARTITIONS}" >&2
947
948# Report existing partition sizes
949adb_sh ls -l /dev/block/by-name/ /dev/block/mapper/ </dev/null 2>/dev/null |
950  sed -n 's@.* \([^ ]*\) -> /dev/block/\([^ ]*\)$@\1 \2@p' |
951  while read name device; do
952    [ super = ${name} -o cache = ${name} ] ||
953      (
954        for i in ${PARTITIONS}; do
955          [ ${i} = ${name} -o ${i} = ${name%_[ab]} ] && exit
956        done
957        exit 1
958      ) ||
959      continue
960
961    case ${device} in
962      sd*)
963        device=${device%%[0-9]*}/${device}
964        ;;
965    esac
966    size=`adb_su cat /sys/block/${device}/size 2>/dev/null </dev/null` &&
967      size=`expr ${size} / 2` &&
968      echo "${BLUE}[     INFO ]${NORMAL} partition ${name} device ${device} size ${size}K" >&2
969  done
970
971# If reboot too soon after fresh flash, could trip device update failure logic
972if ${screen_wait}; then
973  echo "${YELLOW}[  WARNING ]${NORMAL} waiting for screen to come up. Consider --no-wait-screen option" >&2
974fi
975if ! wait_for_screen && ${screen_wait}; then
976  screen_wait=false
977  echo "${YELLOW}[  WARNING ]${NORMAL} not healthy, no launcher, skipping wait for screen" >&2
978fi
979
980# Can we test remount -R command?
981OVERLAYFS_BACKING="cache mnt/scratch"
982overlayfs_supported=true
983if [ "orange" != "`get_property ro.boot.verifiedbootstate`" -o \
984     "2" != "`get_property partition.system.verified`" ]; then
985  restore() {
986    ${overlayfs_supported} || return 0
987    inFastboot &&
988      fastboot reboot &&
989      adb_wait ${ADB_WAIT} ||
990      true
991    if inAdb; then
992      reboot=false
993      for d in ${OVERLAYFS_BACKING}; do
994        if adb_test -d /${d}/overlay; then
995          adb_su rm -rf /${d}/overlay </dev/null
996          reboot=true
997        fi
998      done
999      if ${reboot}; then
1000        adb_reboot &&
1001        adb_wait ${ADB_WAIT}
1002      fi
1003    fi
1004  }
1005else
1006  restore() {
1007    ${overlayfs_supported} || return 0
1008    inFastboot &&
1009      fastboot reboot &&
1010      adb_wait ${ADB_WAIT} ||
1011      true
1012    inAdb &&
1013      adb_root &&
1014      adb enable-verity >/dev/null 2>/dev/null &&
1015      adb_reboot &&
1016      adb_wait ${ADB_WAIT}
1017  }
1018
1019  echo "${GREEN}[ RUN      ]${NORMAL} Testing adb shell su root remount -R command" >&2
1020
1021  avc_check
1022  T=`adb_date`
1023  adb_su remount -R system </dev/null
1024  err=${?}
1025  if [ "${err}" != 0 ]; then
1026    echo "${YELLOW}[  WARNING ]${NORMAL} adb shell su root remount -R system = ${err}, likely did not reboot!" >&2
1027    T="-t ${T}"
1028  else
1029    # Rebooted, logcat will be meaningless, and last logcat will likely be clear
1030    T=""
1031  fi
1032  sleep 2
1033  adb_wait ${ADB_WAIT} ||
1034    die "waiting for device after adb shell su root remount -R system `usb_status`"
1035  if [ "orange" != "`get_property ro.boot.verifiedbootstate`" -o \
1036       "2" = "`get_property partition.system.verified`" ]; then
1037    die ${T} "remount -R command failed
1038${INDENT}ro.boot.verifiedbootstate=\"`get_property ro.boot.verifiedbootstate`\"
1039${INDENT}partition.system.verified=\"`get_property partition.system.verified`\""
1040  fi
1041
1042  echo "${GREEN}[       OK ]${NORMAL} adb shell su root remount -R command" >&2
1043fi
1044
1045echo "${GREEN}[ RUN      ]${NORMAL} Testing kernel support for overlayfs" >&2
1046
1047adb_wait || die "wait for device failed"
1048adb_root ||
1049  die "initial setup"
1050
1051adb_test -d /sys/module/overlay ||
1052  adb_sh grep "nodev${TAB}overlay" /proc/filesystems </dev/null >/dev/null 2>/dev/null &&
1053  echo "${GREEN}[       OK ]${NORMAL} overlay module present" >&2 ||
1054  (
1055    echo "${YELLOW}[  WARNING ]${NORMAL} overlay module not present" >&2 &&
1056      false
1057  ) ||
1058  overlayfs_supported=false
1059if ${overlayfs_supported}; then
1060  adb_test -f /sys/module/overlay/parameters/override_creds &&
1061    echo "${GREEN}[       OK ]${NORMAL} overlay module supports override_creds" >&2 ||
1062    case `adb_sh uname -r </dev/null` in
1063      4.[456789].* | 4.[1-9][0-9]* | [56789].*)
1064        echo "${YELLOW}[  WARNING ]${NORMAL} overlay module does not support override_creds" >&2 &&
1065        overlayfs_supported=false
1066        ;;
1067      *)
1068        echo "${GREEN}[       OK ]${NORMAL} overlay module uses caller's creds" >&2
1069        ;;
1070    esac
1071fi
1072
1073echo "${GREEN}[ RUN      ]${NORMAL} Checking current overlayfs status" >&2
1074
1075# We can not universally use adb enable-verity to ensure device is
1076# in a overlayfs disabled state since it can prevent reboot on
1077# devices that remount the physical content rather than overlayfs.
1078# So lets do our best to surgically wipe the overlayfs state without
1079# having to go through enable-verity transition.
1080reboot=false
1081for d in ${OVERLAYFS_BACKING}; do
1082  if adb_test -d /${d}/overlay; then
1083    echo "${YELLOW}[  WARNING ]${NORMAL} /${d}/overlay is setup, surgically wiping" >&2
1084    adb_sh rm -rf /${d}/overlay </dev/null ||
1085      die "/${d}/overlay wipe"
1086    reboot=true
1087  fi
1088done
1089if ${reboot}; then
1090  echo "${YELLOW}[  WARNING ]${NORMAL} rebooting before test" >&2
1091  adb_reboot &&
1092    adb_wait ${ADB_WAIT} ||
1093    die "lost device after reboot after wipe `usb_status`"
1094  adb_root ||
1095    die "lost device after elevation to root after wipe `usb_status`"
1096fi
1097D=`adb_sh df -k </dev/null` &&
1098  H=`echo "${D}" | head -1` &&
1099  D=`echo "${D}" | grep -v " /vendor/..*$" | grep "^overlay "` &&
1100  echo "${H}" &&
1101  echo "${D}" &&
1102  echo "${YELLOW}[  WARNING ]${NORMAL} overlays present before setup" >&2 ||
1103  echo "${GREEN}[       OK ]${NORMAL} no overlay present before setup" >&2
1104overlayfs_needed=true
1105D=`adb_sh cat /proc/mounts </dev/null |
1106   skip_administrative_mounts data`
1107if echo "${D}" | grep /dev/root >/dev/null; then
1108  D=`echo / /
1109     echo "${D}" | grep -v /dev/root`
1110fi
1111D=`echo "${D}" | cut -s -d' ' -f1 | sort -u`
1112no_dedupe=true
1113for d in ${D}; do
1114  adb_sh tune2fs -l $d </dev/null 2>&1 |
1115    grep "Filesystem features:.*shared_blocks" >/dev/null &&
1116  no_dedupe=false
1117done
1118D=`adb_sh df -k ${D} </dev/null |
1119   sed 's@\([%] /\)\(apex\|bionic\|system\|vendor\)/[^ ][^ ]*$@\1@'`
1120echo "${D}"
1121if [ X"${D}" = X"${D##* 100[%] }" ] && ${no_dedupe} ; then
1122  overlayfs_needed=false
1123  # if device does not need overlays, then adb enable-verity will brick device
1124  restore() {
1125    ${overlayfs_supported} || return 0
1126    inFastboot &&
1127      fastboot reboot &&
1128      adb_wait ${ADB_WAIT}
1129    inAdb &&
1130      adb_wait ${ADB_WAIT}
1131  }
1132elif ! ${overlayfs_supported}; then
1133  die "need overlayfs, but do not have it"
1134fi
1135
1136echo "${GREEN}[ RUN      ]${NORMAL} disable verity" >&2
1137
1138T=`adb_date`
1139H=`adb disable-verity 2>&1`
1140err=${?}
1141L=
1142D="${H%?Now reboot your device for settings to take effect*}"
1143if [ X"${D}" != X"${D##*[Uu]sing overlayfs}" ]; then
1144  echo "${GREEN}[       OK ]${NORMAL} using overlayfs" >&2
1145fi
1146if [ ${err} != 0 ]; then
1147  echo "${H}"
1148  ( [ -n "${L}" ] && echo "${L}" && false ) ||
1149  die -t "${T}" "disable-verity"
1150fi
1151rebooted=false
1152if [ X"${D}" != X"${H}" ]; then
1153  echo "${H}"
1154  if [ X"${D}" != X"${D##*setup failed}" ]; then
1155    echo "${YELLOW}[  WARNING ]${NORMAL} overlayfs setup whined" >&2
1156  fi
1157  D=`adb_sh df -k </dev/null` &&
1158    H=`echo "${D}" | head -1` &&
1159    D=`echo "${D}" | grep -v " /vendor/..*$" | grep "^overlay " || true` &&
1160    [ -z "${D}" ] ||
1161    ( echo "${H}" && echo "${D}" && false ) ||
1162    die -t ${T} "overlay takeover unexpected at this phase"
1163  echo "${GREEN}[     INFO ]${NORMAL} rebooting as requested" >&2
1164  L=`adb_logcat -b all -v nsec -t ${T} 2>&1`
1165  adb_reboot &&
1166    adb_wait ${ADB_WAIT} ||
1167    die "lost device after reboot requested `usb_status`"
1168  adb_root ||
1169    die "lost device after elevation to root `usb_status`"
1170  rebooted=true
1171  # re-disable verity to see the setup remarks expected
1172  T=`adb_date`
1173  H=`adb disable-verity 2>&1`
1174  err=${?}
1175  D="${H%?Now reboot your device for settings to take effect*}"
1176  if [ X"${D}" != X"${D##*[Uu]sing overlayfs}" ]; then
1177    echo "${GREEN}[       OK ]${NORMAL} using overlayfs" >&2
1178  fi
1179  if [ ${err} != 0 ]; then
1180    T=
1181  fi
1182fi
1183if ${overlayfs_supported} && ${overlayfs_needed} && [ X"${D}" != X"${D##*setup failed}" ]; then
1184  echo "${D}"
1185  ( [ -n "${L}" ] && echo "${L}" && false ) ||
1186  die -t "${T}" "setup for overlay"
1187fi
1188if [ X"${D}" != X"${D##*Successfully disabled verity}" ]; then
1189  echo "${H}"
1190  D=`adb_sh df -k </dev/null` &&
1191    H=`echo "${D}" | head -1` &&
1192    D=`echo "${D}" | grep -v " /vendor/..*$" | grep "^overlay " || true` &&
1193    [ -z "${D}" ] ||
1194    ( echo "${H}" && echo "${D}" && false ) ||
1195    ( [ -n "${L}" ] && echo "${L}" && false ) ||
1196    die -t "${T}" "overlay takeover unexpected"
1197  [ -n "${L}" ] && echo "${L}"
1198  die -t "${T}" "unexpected report of verity being disabled a second time"
1199elif ${rebooted}; then
1200  echo "${GREEN}[       OK ]${NORMAL} verity already disabled" >&2
1201else
1202  echo "${YELLOW}[  WARNING ]${NORMAL} verity already disabled" >&2
1203fi
1204
1205echo "${GREEN}[ RUN      ]${NORMAL} remount" >&2
1206
1207# Feed log with selinux denials as baseline before overlays
1208adb_unroot
1209adb_sh find ${MOUNTS} </dev/null >/dev/null 2>/dev/null || true
1210adb_root
1211
1212D=`adb remount 2>&1`
1213ret=${?}
1214echo "${D}"
1215[ ${ret} != 0 ] ||
1216  [ X"${D}" = X"${D##*remount failed}" ] ||
1217  ( [ -n "${L}" ] && echo "${L}" && false ) ||
1218  die -t "${T}" "adb remount failed"
1219D=`adb_sh df -k </dev/null` &&
1220  H=`echo "${D}" | head -1` &&
1221  D=`echo "${D}" | skip_unrelated_mounts | grep "^overlay "` ||
1222  ( [ -n "${L}" ] && echo "${L}" && false )
1223ret=${?}
1224uses_dynamic_scratch=false
1225scratch_partition=
1226virtual_ab=`get_property ro.virtual_ab.enabled`
1227if ${overlayfs_needed}; then
1228  if [ ${ret} != 0 ]; then
1229    die -t ${T} "overlay takeover failed"
1230  fi
1231  echo "${D}" | grep "^overlay .* /system\$" >/dev/null ||
1232   echo "${YELLOW}[  WARNING ]${NORMAL} overlay takeover not complete" >&2
1233  if [ -z "${virtual_ab}" ]; then
1234    scratch_partition=scratch
1235  fi
1236  if echo "${D}" | grep " /mnt/scratch" >/dev/null; then
1237    echo "${BLUE}[     INFO ]${NORMAL} using ${scratch_partition} dynamic partition for overrides" >&2
1238  fi
1239  M=`adb_sh cat /proc/mounts </dev/null |
1240     sed -n 's@\([^ ]*\) /mnt/scratch \([^ ]*\) .*@\2 on \1@p'`
1241  [ -n "${M}" ] &&
1242    echo "${BLUE}[     INFO ]${NORMAL} scratch filesystem ${M}"
1243  uses_dynamic_scratch=true
1244  if [ "${M}" != "${M##*/dev/block/by-name/}" ]; then
1245    uses_dynamic_scratch=false
1246    scratch_partition="${M##*/dev/block/by-name/}"
1247  fi
1248  scratch_size=`adb_sh df -k /mnt/scratch </dev/null 2>/dev/null |
1249                while read device kblocks used available use mounted on; do
1250                  if [ "/mnt/scratch" = "\${mounted}" ]; then
1251                    echo \${kblocks}
1252                  fi
1253                done` &&
1254    [ -n "${scratch_size}" ] ||
1255    die "scratch size"
1256  echo "${BLUE}[     INFO ]${NORMAL} scratch size ${scratch_size}KB" >&2
1257  for d in ${OVERLAYFS_BACKING}; do
1258    if adb_test -d /${d}/overlay/system/upper; then
1259      echo "${BLUE}[     INFO ]${NORMAL} /${d}/overlay is setup" >&2
1260    fi
1261  done
1262
1263  echo "${H}" &&
1264    echo "${D}" &&
1265    echo "${D}" | grep "^overlay .* /system\$" >/dev/null ||
1266    die  "overlay takeover after remount"
1267  !(adb_sh grep "^overlay " /proc/mounts </dev/null |
1268    skip_unrelated_mounts |
1269    grep " overlay ro,") ||
1270    die "remount overlayfs missed a spot (ro)"
1271  !(adb_sh grep -v noatime /proc/mounts </dev/null |
1272    skip_administrative_mounts data |
1273    skip_unrelated_mounts |
1274    grep -v ' ro,') ||
1275    die "mounts are not noatime"
1276  D=`adb_sh grep " rw," /proc/mounts </dev/null |
1277     skip_administrative_mounts data`
1278  if echo "${D}" | grep /dev/root >/dev/null; then
1279    D=`echo / /
1280       echo "${D}" | grep -v /dev/root`
1281  fi
1282  D=`echo "${D}" | cut -s -d' ' -f1 | sort -u`
1283  bad_rw=false
1284  for d in ${D}; do
1285    if adb_sh tune2fs -l $d </dev/null 2>&1 |
1286       grep "Filesystem features:.*shared_blocks" >/dev/null; then
1287      bad_rw=true
1288    else
1289      d=`adb_sh df -k ${D} </dev/null |
1290       sed 's@\([%] /\)\(apex\|bionic\|system\|vendor\)/[^ ][^ ]*$@\1@'`
1291      [ X"${d}" = X"${d##* 100[%] }" ] ||
1292        bad_rw=true
1293    fi
1294  done
1295  [ -z "${D}" ] ||
1296    D=`adb_sh df -k ${D} </dev/null |
1297       sed -e 's@\([%] /\)\(apex\|bionic\|system\|vendor\)/[^ ][^ ]*$@\1@' \
1298           -e 's/^Filesystem      /Filesystem (rw) /'`
1299  [ -z "${D}" ] || echo "${D}"
1300  ${bad_rw} && die "remount overlayfs missed a spot (rw)"
1301else
1302  if [ ${ret} = 0 ]; then
1303    die -t ${T} "unexpected overlay takeover"
1304  fi
1305fi
1306
1307# Check something.
1308
1309echo "${GREEN}[ RUN      ]${NORMAL} push content to ${MOUNTS}" >&2
1310
1311A="Hello World! $(date)"
1312for i in ${MOUNTS}; do
1313  echo "${A}" | adb_sh cat - ">${i}/hello"
1314  B="`adb_cat ${i}/hello`" ||
1315    die "${i#/} hello"
1316  check_eq "${A}" "${B}" ${i} before reboot
1317done
1318echo "${A}" | adb_sh cat - ">/system/priv-app/hello"
1319B="`adb_cat /system/priv-app/hello`" ||
1320  die "system priv-app hello"
1321check_eq "${A}" "${B}" /system/priv-app before reboot
1322SYSTEM_DEVT=`adb_sh stat --format=%D /system/hello </dev/null`
1323VENDOR_DEVT=`adb_sh stat --format=%D /vendor/hello </dev/null`
1324SYSTEM_INO=`adb_sh stat --format=%i /system/hello </dev/null`
1325VENDOR_INO=`adb_sh stat --format=%i /vendor/hello </dev/null`
1326BASE_SYSTEM_DEVT=`adb_sh stat --format=%D /system/bin/stat </dev/null`
1327BASE_VENDOR_DEVT=`adb_sh stat --format=%D /vendor/bin/stat </dev/null`
1328check_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
1329check_ne "${SYSTEM_INO}" "${VENDOR_INO}" vendor and system inode
1330if ${overlayfs_needed}; then
1331  check_ne "${SYSTEM_DEVT}" "${BASE_SYSTEM_DEVT}" system devt
1332  check_ne "${VENDOR_DEVT}" "${BASE_VENDOR_DEVT}" vendor devt
1333else
1334  check_eq "${SYSTEM_DEVT}" "${BASE_SYSTEM_DEVT}" system devt
1335  check_eq "${VENDOR_DEVT}" "${BASE_VENDOR_DEVT}" vendor devt
1336fi
1337check_ne "${BASE_SYSTEM_DEVT}" "${BASE_VENDOR_DEVT}" --warning system/vendor devt
1338[ -n "${SYSTEM_DEVT%[0-9a-fA-F][0-9a-fA-F]}" ] ||
1339  echo "${YELLOW}[  WARNING ]${NORMAL} system devt ${SYSTEM_DEVT} major 0" >&2
1340[ -n "${VENDOR_DEVT%[0-9a-fA-F][0-9a-fA-F]}" ] ||
1341  echo "${YELLOW}[  WARNING ]${NORMAL} vendor devt ${VENDOR_DEVT} major 0" >&2
1342
1343# Download libc.so, append some garbage, push back, and check if the file
1344# is updated.
1345tempdir="`mktemp -d`"
1346cleanup() {
1347  rm -rf ${tempdir}
1348}
1349adb pull /system/lib/bootstrap/libc.so ${tempdir} >/dev/null ||
1350  die "pull libc.so from device"
1351garbage="D105225BBFCB1EB8AB8EBDB7094646F0"
1352echo "${garbage}" >> ${tempdir}/libc.so
1353adb push ${tempdir}/libc.so /system/lib/bootstrap/libc.so >/dev/null ||
1354  die "push libc.so to device"
1355adb pull /system/lib/bootstrap/libc.so ${tempdir}/libc.so.fromdevice >/dev/null ||
1356  die "pull libc.so from device"
1357diff ${tempdir}/libc.so ${tempdir}/libc.so.fromdevice > /dev/null ||
1358  die "libc.so differ"
1359
1360echo "${GREEN}[ RUN      ]${NORMAL} reboot to confirm content persistent" >&2
1361
1362fixup_from_recovery() {
1363  inRecovery || return 1
1364  echo "${YELLOW}[    ERROR ]${NORMAL} Device in recovery" >&2
1365  adb reboot </dev/null
1366  adb_wait ${ADB_WAIT}
1367}
1368
1369adb_reboot &&
1370  adb_wait ${ADB_WAIT} ||
1371  fixup_from_recovery ||
1372  die "reboot after override content added failed `usb_status`"
1373
1374if ${overlayfs_needed}; then
1375  D=`adb_su df -k </dev/null` &&
1376    H=`echo "${D}" | head -1` &&
1377    D=`echo "${D}" | grep -v " /vendor/..*$" | grep "^overlay "` ||
1378    ( echo "${L}" && false ) ||
1379    die -d "overlay takeover failed after reboot"
1380
1381  adb_su sed -n '1,/overlay \/system/p' /proc/mounts </dev/null |
1382    skip_administrative_mounts |
1383    grep -v ' \(erofs\|squashfs\|ext4\|f2fs\|vfat\) ' &&
1384    echo "${YELLOW}[  WARNING ]${NORMAL} overlay takeover after first stage init" >&2 ||
1385    echo "${GREEN}[       OK ]${NORMAL} overlay takeover in first stage init" >&2
1386fi
1387
1388if ${enforcing}; then
1389  adb_unroot ||
1390    die "device not in unroot'd state"
1391  B="`adb_cat /vendor/hello 2>&1`"
1392  check_eq "cat: /vendor/hello: Permission denied" "${B}" vendor after reboot w/o root
1393  echo "${GREEN}[       OK ]${NORMAL} /vendor content correct MAC after reboot" >&2
1394  # Feed unprivileged log with selinux denials as a result of overlays
1395  wait_for_screen
1396  adb_sh find ${MOUNTS} </dev/null >/dev/null 2>/dev/null || true
1397fi
1398# If overlayfs has a nested security problem, this will fail.
1399B="`adb_ls /system/`" ||
1400  die "adb ls /system"
1401[ X"${B}" != X"${B#*priv-app}" ] ||
1402  die "adb ls /system/priv-app"
1403B="`adb_cat /system/priv-app/hello`"
1404check_eq "${A}" "${B}" /system/priv-app after reboot
1405# Only root can read vendor if sepolicy permissions are as expected.
1406adb_root ||
1407  die "adb root"
1408for i in ${MOUNTS}; do
1409  B="`adb_cat ${i}/hello`"
1410  check_eq "${A}" "${B}" ${i#/} after reboot
1411  echo "${GREEN}[       OK ]${NORMAL} ${i} content remains after reboot" >&2
1412done
1413
1414check_eq "${SYSTEM_DEVT}" "`adb_sh stat --format=%D /system/hello </dev/null`" system devt after reboot
1415check_eq "${VENDOR_DEVT}" "`adb_sh stat --format=%D /vendor/hello </dev/null`" vendor devt after reboot
1416check_eq "${SYSTEM_INO}" "`adb_sh stat --format=%i /system/hello </dev/null`" system inode after reboot
1417check_eq "${VENDOR_INO}" "`adb_sh stat --format=%i /vendor/hello </dev/null`" vendor inode after reboot
1418check_eq "${BASE_SYSTEM_DEVT}" "`adb_sh stat --format=%D /system/bin/stat </dev/null`" --warning base system devt after reboot
1419check_eq "${BASE_VENDOR_DEVT}" "`adb_sh stat --format=%D /vendor/bin/stat </dev/null`" --warning base vendor devt after reboot
1420check_eq "${BASE_SYSTEM_DEVT}" "`adb_sh stat --format=%D /system/xbin/su </dev/null`" --warning devt for su after reboot
1421
1422# Feed log with selinux denials as a result of overlays
1423adb_sh find ${MOUNTS} </dev/null >/dev/null 2>/dev/null || true
1424
1425# Check if the updated libc.so is persistent after reboot.
1426adb_root &&
1427  adb pull /system/lib/bootstrap/libc.so ${tempdir}/libc.so.fromdevice >/dev/null ||
1428  die "pull libc.so from device"
1429diff ${tempdir}/libc.so ${tempdir}/libc.so.fromdevice > /dev/null || die "libc.so differ"
1430rm -rf ${tempdir}
1431cleanup() {
1432  true
1433}
1434echo "${GREEN}[       OK ]${NORMAL} /system/lib/bootstrap/libc.so content remains after reboot" >&2
1435
1436echo "${GREEN}[ RUN      ]${NORMAL} flash vendor, confirm its content disappears" >&2
1437
1438H=`adb_sh echo '${HOSTNAME}' </dev/null 2>/dev/null`
1439is_bootloader_fastboot=false
1440# cuttlefish?
1441[ X"${H}" != X"${H#vsoc}" ] || is_bootloader_fastboot=true
1442is_userspace_fastboot=false
1443
1444if ! ${is_bootloader_fastboot}; then
1445  echo "${YELLOW}[  WARNING ]${NORMAL} does not support fastboot, skipping"
1446elif [ -z "${ANDROID_PRODUCT_OUT}" ]; then
1447  echo "${YELLOW}[  WARNING ]${NORMAL} build tree not setup, skipping"
1448elif [ ! -s "${ANDROID_PRODUCT_OUT}/vendor.img" ]; then
1449  echo "${YELLOW}[  WARNING ]${NORMAL} vendor image missing, skipping"
1450elif [ "${ANDROID_PRODUCT_OUT}" = "${ANDROID_PRODUCT_OUT%*/${H}}" ]; then
1451  echo "${YELLOW}[  WARNING ]${NORMAL} wrong vendor image, skipping"
1452elif [ -z "${ANDROID_HOST_OUT}" ]; then
1453  echo "${YELLOW}[  WARNING ]${NORMAL} please run lunch, skipping"
1454elif ! (
1455          adb_cat /vendor/build.prop |
1456          cmp -s ${ANDROID_PRODUCT_OUT}/vendor/build.prop
1457       ) >/dev/null 2>/dev/null; then
1458  echo "${YELLOW}[  WARNING ]${NORMAL} vendor image signature mismatch, skipping"
1459else
1460  wait_for_screen
1461  avc_check
1462  adb reboot fastboot </dev/null ||
1463    die "fastbootd not supported (wrong adb in path?)"
1464  any_wait ${ADB_WAIT} &&
1465    inFastboot ||
1466    die "reboot into fastboot to flash vendor `usb_status` (bad bootloader?)"
1467  fastboot flash vendor ||
1468    ( fastboot reboot && false) ||
1469    die "fastboot flash vendor"
1470  fastboot_getvar is-userspace yes &&
1471    is_userspace_fastboot=true
1472  if [ -n "${scratch_paritition}" ]; then
1473    fastboot_getvar partition-type:${scratch_partition} raw ||
1474      ( fastboot reboot && false) ||
1475      die "fastboot can not see ${scratch_partition} parameters"
1476    if ${uses_dynamic_scratch}; then
1477      # check ${scratch_partition} via fastboot
1478      fastboot_getvar has-slot:${scratch_partition} no &&
1479        fastboot_getvar is-logical:${scratch_partition} yes ||
1480        ( fastboot reboot && false) ||
1481        die "fastboot can not see ${scratch_partition} parameters"
1482    else
1483      fastboot_getvar is-logical:${scratch_partition} no ||
1484        ( fastboot reboot && false) ||
1485        die "fastboot can not see ${scratch_partition} parameters"
1486    fi
1487    if ! ${uses_dynamic_scratch}; then
1488      fastboot reboot-bootloader ||
1489        die "Reboot into fastboot"
1490    fi
1491    if ${uses_dynamic_scratch}; then
1492      echo "${BLUE}[     INFO ]${NORMAL} expect fastboot erase ${scratch_partition} to fail" >&2
1493      fastboot erase ${scratch_partition} &&
1494        ( fastboot reboot || true) &&
1495        die "fastboot can erase ${scratch_partition}"
1496    fi
1497    echo "${BLUE}[     INFO ]${NORMAL} expect fastboot format ${scratch_partition} to fail" >&2
1498    fastboot format ${scratch_partition} &&
1499      ( fastboot reboot || true) &&
1500      die "fastboot can format ${scratch_partition}"
1501  fi
1502  fastboot reboot ||
1503    die "can not reboot out of fastboot"
1504  echo "${YELLOW}[  WARNING ]${NORMAL} adb after fastboot"
1505  adb_wait ${ADB_WAIT} ||
1506    fixup_from_recovery ||
1507    die "did not reboot after formatting ${scratch_partition} `usb_status`"
1508  if ${overlayfs_needed}; then
1509    adb_root &&
1510      D=`adb_sh df -k </dev/null` &&
1511      H=`echo "${D}" | head -1` &&
1512      D=`echo "${D}" | skip_unrelated_mounts | grep "^overlay "` &&
1513      echo "${H}" &&
1514      echo "${D}" &&
1515      echo "${D}" | grep "^overlay .* /system\$" >/dev/null ||
1516      die  "overlay /system takeover after flash vendor"
1517    echo "${D}" | grep "^overlay .* /vendor\$" >/dev/null &&
1518      if ${is_userspace_fastboot}; then
1519        die  "overlay supposed to be minus /vendor takeover after flash vendor"
1520      else
1521        echo "${YELLOW}[  WARNING ]${NORMAL} user fastboot missing required to invalidate, ignoring a failure" >&2
1522        echo "${YELLOW}[  WARNING ]${NORMAL} overlay supposed to be minus /vendor takeover after flash vendor" >&2
1523      fi
1524  fi
1525  B="`adb_cat /system/hello`"
1526  check_eq "${A}" "${B}" system after flash vendor
1527  B="`adb_ls /system/`" ||
1528    die "adb ls /system"
1529  [ X"${B}" != X"${B#*priv-app}" ] ||
1530    die "adb ls /system/priv-app"
1531  B="`adb_cat /system/priv-app/hello`"
1532  check_eq "${A}" "${B}" system/priv-app after flash vendor
1533  adb_root ||
1534    die "adb root"
1535  B="`adb_cat /vendor/hello`"
1536  if ${is_userspace_fastboot} || ! ${overlayfs_needed}; then
1537    check_eq "cat: /vendor/hello: No such file or directory" "${B}" \
1538             vendor content after flash vendor
1539  else
1540    echo "${YELLOW}[  WARNING ]${NORMAL} user fastboot missing required to invalidate, ignoring a failure" >&2
1541    check_eq "cat: /vendor/hello: No such file or directory" "${B}" \
1542             --warning vendor content after flash vendor
1543  fi
1544
1545  check_eq "${SYSTEM_DEVT}" "`adb_sh stat --format=%D /system/hello </dev/null`" system devt after reboot
1546  check_eq "${SYSTEM_INO}" "`adb_sh stat --format=%i /system/hello </dev/null`" system inode after reboot
1547  check_eq "${BASE_SYSTEM_DEVT}" "`adb_sh stat --format=%D /system/bin/stat </dev/null`" --warning base system devt after reboot
1548  check_eq "${BASE_SYSTEM_DEVT}" "`adb_sh stat --format=%D /system/xbin/su </dev/null`" --warning devt for su after reboot
1549
1550fi
1551
1552wait_for_screen
1553echo "${GREEN}[ RUN      ]${NORMAL} remove test content (cleanup)" >&2
1554
1555T=`adb_date`
1556H=`adb remount 2>&1`
1557err=${?}
1558L=
1559D="${H%?Now reboot your device for settings to take effect*}"
1560if [ X"${H}" != X"${D}" ]; then
1561  echo "${YELLOW}[  WARNING ]${NORMAL} adb remount requires a reboot after partial flash (legacy avb)"
1562  L=`adb_logcat -b all -v nsec -t ${T} 2>&1`
1563  adb_reboot &&
1564    adb_wait ${ADB_WAIT} &&
1565    adb_root ||
1566    die "failed to reboot"
1567  T=`adb_date`
1568  H=`adb remount 2>&1`
1569  err=${?}
1570fi
1571echo "${H}"
1572[ ${err} = 0 ] &&
1573  ( adb_sh rm /vendor/hello </dev/null 2>/dev/null || true ) &&
1574  adb_sh rm /system/hello /system/priv-app/hello </dev/null ||
1575  ( [ -n "${L}" ] && echo "${L}" && false ) ||
1576  die -t ${T} "cleanup hello"
1577B="`adb_cat /system/hello`"
1578check_eq "cat: /system/hello: No such file or directory" "${B}" after rm
1579B="`adb_cat /system/priv-app/hello`"
1580check_eq "cat: /system/priv-app/hello: No such file or directory" "${B}" after rm
1581B="`adb_cat /vendor/hello`"
1582check_eq "cat: /vendor/hello: No such file or directory" "${B}" after rm
1583for i in ${MOUNTS}; do
1584  adb_sh rm ${i}/hello </dev/null 2>/dev/null || true
1585done
1586
1587if ${is_bootloader_fastboot} && [ -n "${scratch_partition}" ]; then
1588
1589  echo "${GREEN}[ RUN      ]${NORMAL} test fastboot flash to ${scratch_partition} recovery" >&2
1590
1591  avc_check
1592  adb reboot fastboot </dev/null ||
1593    die "Reboot into fastbootd"
1594  img=${TMPDIR}/adb-remount-test-${$}.img
1595  cleanup() {
1596    rm ${img}
1597  }
1598  dd if=/dev/zero of=${img} bs=4096 count=16 2>/dev/null &&
1599    fastboot_wait ${FASTBOOT_WAIT} ||
1600    die "reboot into fastboot to flash scratch `usb_status`"
1601  fastboot flash --force ${scratch_partition} ${img}
1602  err=${?}
1603  cleanup
1604  cleanup() {
1605    true
1606  }
1607  fastboot reboot ||
1608    die "can not reboot out of fastboot"
1609  [ 0 -eq ${err} ] ||
1610    die "fastboot flash ${scratch_partition}"
1611  adb_wait ${ADB_WAIT} &&
1612    adb_root ||
1613    die "did not reboot after flashing empty ${scratch_partition} `usb_status`"
1614  T=`adb_date`
1615  D=`adb disable-verity 2>&1`
1616  err=${?}
1617  if [ X"${D}" != "${D%?Now reboot your device for settings to take effect*}" ]
1618  then
1619    echo "${YELLOW}[  WARNING ]${NORMAL} adb disable-verity requires a reboot after partial flash"
1620    adb_reboot &&
1621      adb_wait ${ADB_WAIT} &&
1622      adb_root ||
1623      die "failed to reboot"
1624    T=`adb_date`
1625    D="${D}
1626`adb disable-verity 2>&1`"
1627    err=${?}
1628  fi
1629
1630  echo "${D}"
1631  [ ${err} = 0 ] &&
1632    [ X"${D}" = X"${D##*setup failed}" ] &&
1633    [ X"${D}" != X"${D##*[Uu]sing overlayfs}" ] &&
1634    echo "${GREEN}[       OK ]${NORMAL} ${scratch_partition} recreated" >&2 ||
1635    die -t ${T} "setup for overlayfs"
1636  D=`adb remount 2>&1`
1637  err=${?}
1638  echo "${D}"
1639  [ ${err} != 0 ] ||
1640    [ X"${D}" = X"${D##*remount failed}" ] ||
1641    ( echo "${D}" && false ) ||
1642    die -t ${T} "remount failed"
1643fi
1644
1645echo "${GREEN}[ RUN      ]${NORMAL} test raw remount commands" >&2
1646
1647fixup_from_fastboot() {
1648  inFastboot || return 1
1649  if [ -n "${ACTIVE_SLOT}" ]; then
1650    local active_slot=`get_active_slot`
1651    if [ X"${ACTIVE_SLOT}" != X"${active_slot}" ]; then
1652      echo "${YELLOW}[    ERROR ]${NORMAL} Active slot changed from ${ACTIVE_SLOT} to ${active_slot}"
1653    else
1654      echo "${YELLOW}[    ERROR ]${NORMAL} Active slot to be set to ${ACTIVE_SLOT}"
1655    fi >&2
1656    fastboot --set-active=${ACTIVE_SLOT}
1657  fi
1658  fastboot reboot
1659  adb_wait ${ADB_WAIT}
1660}
1661
1662# Prerequisite is a prepped device from above.
1663adb_reboot &&
1664  adb_wait ${ADB_WAIT} ||
1665  fixup_from_fastboot ||
1666  die "lost device after reboot to ro state `usb_status`"
1667adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null &&
1668  die "/vendor is not read-only"
1669adb_su mount -o rw,remount /vendor </dev/null ||
1670  die "remount command"
1671adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null ||
1672  die "/vendor is not read-write"
1673echo "${GREEN}[       OK ]${NORMAL} mount -o rw,remount command works" >&2
1674
1675# Prerequisite is a prepped device from above.
1676adb_reboot &&
1677  adb_wait ${ADB_WAIT} ||
1678  fixup_from_fastboot ||
1679  die "lost device after reboot to ro state `usb_status`"
1680adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null &&
1681  die "/vendor is not read-only"
1682adb_su remount vendor </dev/null ||
1683  die "remount command"
1684adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null ||
1685  die "/vendor is not read-write"
1686adb_sh grep " /system .* rw," /proc/mounts >/dev/null </dev/null &&
1687  die "/vendor is not read-only"
1688echo "${GREEN}[       OK ]${NORMAL} remount command works from setup" >&2
1689
1690# Prerequisite is an overlayfs deconstructed device but with verity disabled.
1691# This also saves a lot of 'noise' from the command doing a mkfs on backing
1692# storage and all the related tuning and adjustment.
1693for d in ${OVERLAYFS_BACKING}; do
1694  if adb_test -d /${d}/overlay; then
1695    adb_su rm -rf /${d}/overlay </dev/null ||
1696      die "/${d}/overlay wipe"
1697  fi
1698done
1699adb_reboot &&
1700  adb_wait ${ADB_WAIT} ||
1701  fixup_from_fastboot ||
1702  die "lost device after reboot after wipe `usb_status`"
1703adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null &&
1704  die "/vendor is not read-only"
1705adb_su remount vendor </dev/null ||
1706  die "remount command"
1707adb_su df -k </dev/null | skip_unrelated_mounts
1708adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null ||
1709  die "/vendor is not read-write"
1710adb_sh grep " \(/system\|/\) .* rw," /proc/mounts >/dev/null </dev/null &&
1711  die "/system is not read-only"
1712echo "${GREEN}[       OK ]${NORMAL} remount command works from scratch" >&2
1713
1714if ! restore; then
1715  restore() {
1716    true
1717  }
1718  die "failed to restore verity after remount from scratch test"
1719fi
1720
1721err=0
1722
1723if ${overlayfs_supported}; then
1724  echo "${GREEN}[ RUN      ]${NORMAL} test 'adb remount -R'" >&2
1725  avc_check
1726  adb_root ||
1727    die "adb root in preparation for adb remount -R"
1728  T=`adb_date`
1729  adb remount -R
1730  err=${?}
1731  if [ "${err}" != 0 ]; then
1732    die -t ${T} "adb remount -R = ${err}"
1733  fi
1734  sleep 2
1735  adb_wait ${ADB_WAIT} ||
1736    die "waiting for device after adb remount -R `usb_status`"
1737  if [ "orange" != "`get_property ro.boot.verifiedbootstate`" -o \
1738       "2" = "`get_property partition.system.verified`" ] &&
1739     [ -n "`get_property ro.boot.verifiedbootstate`" -o \
1740       -n "`get_property partition.system.verified`" ]; then
1741    die "remount -R command failed to disable verity
1742${INDENT}ro.boot.verifiedbootstate=\"`get_property ro.boot.verifiedbootstate`\"
1743${INDENT}partition.system.verified=\"`get_property partition.system.verified`\""
1744  fi
1745
1746  echo "${GREEN}[       OK ]${NORMAL} 'adb remount -R' command" >&2
1747
1748  restore
1749  err=${?}
1750fi
1751
1752restore() {
1753  true
1754}
1755
1756[ ${err} = 0 ] ||
1757  die "failed to restore verity"
1758
1759echo "${GREEN}[  PASSED  ]${NORMAL} adb remount" >&2
1760
1761test_duration
1762