xref: /openbsd-src/gnu/llvm/compiler-rt/lib/asan/scripts/asan_device_setup (revision 810390e339a5425391477d5d41c78d7cab2424ac)
1*810390e3Srobert#!/usr/bin/env bash
23cab2bb3Spatrick#===- lib/asan/scripts/asan_device_setup -----------------------------------===#
33cab2bb3Spatrick#
43cab2bb3Spatrick# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
53cab2bb3Spatrick# See https://llvm.org/LICENSE.txt for license information.
63cab2bb3Spatrick# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
73cab2bb3Spatrick#
83cab2bb3Spatrick# Prepare Android device to run ASan applications.
93cab2bb3Spatrick#
103cab2bb3Spatrick#===------------------------------------------------------------------------===#
113cab2bb3Spatrick
123cab2bb3Spatrickset -e
133cab2bb3Spatrick
143cab2bb3SpatrickHERE="$(cd "$(dirname "$0")" && pwd)"
153cab2bb3Spatrick
163cab2bb3Spatrickrevert=no
173cab2bb3Spatrickextra_options=
183cab2bb3Spatrickdevice=
193cab2bb3Spatricklib=
203cab2bb3Spatrickuse_su=0
213cab2bb3Spatrick
223cab2bb3Spatrickfunction usage {
233cab2bb3Spatrick    echo "usage: $0 [--revert] [--device device-id] [--lib path] [--extra-options options]"
243cab2bb3Spatrick    echo "  --revert: Uninstall ASan from the device."
253cab2bb3Spatrick    echo "  --lib: Path to ASan runtime library."
263cab2bb3Spatrick    echo "  --extra-options: Extra ASAN_OPTIONS."
273cab2bb3Spatrick    echo "  --device: Install to the given device. Use 'adb devices' to find"
283cab2bb3Spatrick    echo "            device-id."
293cab2bb3Spatrick    echo "  --use-su: Use 'su -c' prefix for every adb command instead of using"
303cab2bb3Spatrick    echo "            'adb root' once."
313cab2bb3Spatrick    echo
323cab2bb3Spatrick    exit 1
333cab2bb3Spatrick}
343cab2bb3Spatrick
353cab2bb3Spatrickfunction adb_push {
363cab2bb3Spatrick  if [ $use_su -eq 0 ]; then
373cab2bb3Spatrick    $ADB push "$1" "$2"
383cab2bb3Spatrick  else
393cab2bb3Spatrick    local FILENAME=$(basename $1)
403cab2bb3Spatrick    $ADB push "$1" "/data/local/tmp/$FILENAME"
413cab2bb3Spatrick    $ADB shell su -c "rm \\\"$2/$FILENAME\\\"" >&/dev/null
423cab2bb3Spatrick    $ADB shell su -c "cat \\\"/data/local/tmp/$FILENAME\\\" > \\\"$2/$FILENAME\\\""
433cab2bb3Spatrick    $ADB shell su -c "rm \\\"/data/local/tmp/$FILENAME\\\""
443cab2bb3Spatrick  fi
453cab2bb3Spatrick}
463cab2bb3Spatrick
473cab2bb3Spatrickfunction adb_remount {
483cab2bb3Spatrick  if [ $use_su -eq 0 ]; then
493cab2bb3Spatrick    $ADB remount
503cab2bb3Spatrick  else
513cab2bb3Spatrick    local STORAGE=`$ADB shell mount | grep /system | cut -d ' ' -f1`
523cab2bb3Spatrick    if [ "$STORAGE" != "" ]; then
533cab2bb3Spatrick      echo Remounting $STORAGE at /system
543cab2bb3Spatrick      $ADB shell su -c "mount -o rw,remount $STORAGE /system"
553cab2bb3Spatrick    else
563cab2bb3Spatrick      echo Failed to get storage device name for "/system" mount point
573cab2bb3Spatrick    fi
583cab2bb3Spatrick  fi
593cab2bb3Spatrick}
603cab2bb3Spatrick
613cab2bb3Spatrickfunction adb_shell {
623cab2bb3Spatrick  if [ $use_su -eq 0 ]; then
633cab2bb3Spatrick    $ADB shell $@
643cab2bb3Spatrick  else
653cab2bb3Spatrick    $ADB shell su -c "$*"
663cab2bb3Spatrick  fi
673cab2bb3Spatrick}
683cab2bb3Spatrick
693cab2bb3Spatrickfunction adb_root {
703cab2bb3Spatrick  if [ $use_su -eq 0 ]; then
713cab2bb3Spatrick    $ADB root
723cab2bb3Spatrick  fi
733cab2bb3Spatrick}
743cab2bb3Spatrick
753cab2bb3Spatrickfunction adb_wait_for_device {
763cab2bb3Spatrick  $ADB wait-for-device
773cab2bb3Spatrick}
783cab2bb3Spatrick
793cab2bb3Spatrickfunction adb_pull {
803cab2bb3Spatrick  if [ $use_su -eq 0 ]; then
813cab2bb3Spatrick    $ADB pull "$1" "$2"
823cab2bb3Spatrick  else
833cab2bb3Spatrick    local FILENAME=$(basename $1)
843cab2bb3Spatrick    $ADB shell rm "/data/local/tmp/$FILENAME" >&/dev/null
853cab2bb3Spatrick    $ADB shell su -c "[ -f \\\"$1\\\" ] && cat \\\"$1\\\" > \\\"/data/local/tmp/$FILENAME\\\" && chown root.shell \\\"/data/local/tmp/$FILENAME\\\" && chmod 755 \\\"/data/local/tmp/$FILENAME\\\"" &&
863cab2bb3Spatrick    $ADB pull "/data/local/tmp/$FILENAME" "$2" >&/dev/null && $ADB shell "rm \"/data/local/tmp/$FILENAME\""
873cab2bb3Spatrick  fi
883cab2bb3Spatrick}
893cab2bb3Spatrick
903cab2bb3Spatrickfunction get_device_arch { # OUT OUT64
913cab2bb3Spatrick    local _outvar=$1
923cab2bb3Spatrick    local _outvar64=$2
933cab2bb3Spatrick    local _ABI=$(adb_shell getprop ro.product.cpu.abi)
943cab2bb3Spatrick    local _ARCH=
953cab2bb3Spatrick    local _ARCH64=
963cab2bb3Spatrick    if [[ $_ABI == x86* ]]; then
97d89ec533Spatrick        _ARCH=i686
983cab2bb3Spatrick    elif [[ $_ABI == armeabi* ]]; then
993cab2bb3Spatrick        _ARCH=arm
1003cab2bb3Spatrick    elif [[ $_ABI == arm64-v8a* ]]; then
1013cab2bb3Spatrick        _ARCH=arm
1023cab2bb3Spatrick        _ARCH64=aarch64
1033cab2bb3Spatrick    else
1043cab2bb3Spatrick        echo "Unrecognized device ABI: $_ABI"
1053cab2bb3Spatrick        exit 1
1063cab2bb3Spatrick    fi
1073cab2bb3Spatrick    eval $_outvar=\$_ARCH
1083cab2bb3Spatrick    eval $_outvar64=\$_ARCH64
1093cab2bb3Spatrick}
1103cab2bb3Spatrick
1113cab2bb3Spatrickwhile [[ $# > 0 ]]; do
1123cab2bb3Spatrick  case $1 in
1133cab2bb3Spatrick    --revert)
1143cab2bb3Spatrick      revert=yes
1153cab2bb3Spatrick      ;;
1163cab2bb3Spatrick    --extra-options)
1173cab2bb3Spatrick      shift
1183cab2bb3Spatrick      if [[ $# == 0 ]]; then
1193cab2bb3Spatrick        echo "--extra-options requires an argument."
1203cab2bb3Spatrick        exit 1
1213cab2bb3Spatrick      fi
1223cab2bb3Spatrick      extra_options="$1"
1233cab2bb3Spatrick      ;;
1243cab2bb3Spatrick    --lib)
1253cab2bb3Spatrick      shift
1263cab2bb3Spatrick      if [[ $# == 0 ]]; then
1273cab2bb3Spatrick        echo "--lib requires an argument."
1283cab2bb3Spatrick        exit 1
1293cab2bb3Spatrick      fi
1303cab2bb3Spatrick      lib="$1"
1313cab2bb3Spatrick      ;;
1323cab2bb3Spatrick    --device)
1333cab2bb3Spatrick      shift
1343cab2bb3Spatrick      if [[ $# == 0 ]]; then
1353cab2bb3Spatrick        echo "--device requires an argument."
1363cab2bb3Spatrick        exit 1
1373cab2bb3Spatrick      fi
1383cab2bb3Spatrick      device="$1"
1393cab2bb3Spatrick      ;;
1403cab2bb3Spatrick    --use-su)
1413cab2bb3Spatrick      use_su=1
1423cab2bb3Spatrick      ;;
1433cab2bb3Spatrick    *)
1443cab2bb3Spatrick      usage
1453cab2bb3Spatrick      ;;
1463cab2bb3Spatrick  esac
1473cab2bb3Spatrick  shift
1483cab2bb3Spatrickdone
1493cab2bb3Spatrick
1503cab2bb3SpatrickADB=${ADB:-adb}
1513cab2bb3Spatrickif [[ x$device != x ]]; then
1523cab2bb3Spatrick    ADB="$ADB -s $device"
1533cab2bb3Spatrickfi
1543cab2bb3Spatrick
1553cab2bb3Spatrickif [ $use_su -eq 1 ]; then
1563cab2bb3Spatrick  # Test if 'su' is present on the device
1573cab2bb3Spatrick  SU_TEST_OUT=`$ADB shell su -c "echo foo" 2>&1 | sed 's/\r$//'`
1583cab2bb3Spatrick  if [ $? != 0 -o "$SU_TEST_OUT" != "foo" ]; then
1593cab2bb3Spatrick    echo "ERROR: Cannot use 'su -c':"
1603cab2bb3Spatrick    echo "$ adb shell su -c \"echo foo\""
1613cab2bb3Spatrick    echo $SU_TEST_OUT
1623cab2bb3Spatrick    echo "Check that 'su' binary is correctly installed on the device or omit"
1633cab2bb3Spatrick    echo "            --use-su flag"
1643cab2bb3Spatrick    exit 1
1653cab2bb3Spatrick  fi
1663cab2bb3Spatrickfi
1673cab2bb3Spatrick
1683cab2bb3Spatrickecho '>> Remounting /system rw'
1693cab2bb3Spatrickadb_wait_for_device
1703cab2bb3Spatrickadb_root
1713cab2bb3Spatrickadb_wait_for_device
1723cab2bb3Spatrickadb_remount
1733cab2bb3Spatrickadb_wait_for_device
1743cab2bb3Spatrick
1753cab2bb3Spatrickget_device_arch ARCH ARCH64
1763cab2bb3Spatrickecho "Target architecture: $ARCH"
1773cab2bb3SpatrickASAN_RT="libclang_rt.asan-$ARCH-android.so"
1783cab2bb3Spatrickif [[ -n $ARCH64 ]]; then
1793cab2bb3Spatrick  echo "Target architecture: $ARCH64"
1803cab2bb3Spatrick  ASAN_RT64="libclang_rt.asan-$ARCH64-android.so"
1813cab2bb3Spatrickfi
1823cab2bb3Spatrick
1833cab2bb3SpatrickRELEASE=$(adb_shell getprop ro.build.version.release)
1843cab2bb3SpatrickPRE_L=0
1853cab2bb3Spatrickif echo "$RELEASE" | grep '^4\.' >&/dev/null; then
1863cab2bb3Spatrick    PRE_L=1
1873cab2bb3Spatrickfi
1883cab2bb3SpatrickANDROID_O=0
1893cab2bb3Spatrickif echo "$RELEASE" | grep '^8\.0\.' >&/dev/null; then
1903cab2bb3Spatrick    # 8.0.x is for Android O
1913cab2bb3Spatrick    ANDROID_O=1
1923cab2bb3Spatrickfi
1933cab2bb3Spatrick
1943cab2bb3Spatrickif [[ x$revert == xyes ]]; then
1953cab2bb3Spatrick    echo '>> Uninstalling ASan'
1963cab2bb3Spatrick
1973cab2bb3Spatrick    if ! adb_shell ls -l /system/bin/app_process | grep -o '\->.*app_process' >&/dev/null; then
1983cab2bb3Spatrick      echo '>> Pre-L device detected.'
1993cab2bb3Spatrick      adb_shell mv /system/bin/app_process.real /system/bin/app_process
2003cab2bb3Spatrick      adb_shell rm /system/bin/asanwrapper
2013cab2bb3Spatrick    elif ! adb_shell ls -l /system/bin/app_process64.real | grep -o 'No such file or directory' >&/dev/null; then
2023cab2bb3Spatrick      # 64-bit installation.
2033cab2bb3Spatrick      adb_shell mv /system/bin/app_process32.real /system/bin/app_process32
2043cab2bb3Spatrick      adb_shell mv /system/bin/app_process64.real /system/bin/app_process64
2053cab2bb3Spatrick      adb_shell rm /system/bin/asanwrapper
2063cab2bb3Spatrick      adb_shell rm /system/bin/asanwrapper64
2073cab2bb3Spatrick    else
2083cab2bb3Spatrick      # 32-bit installation.
2093cab2bb3Spatrick      adb_shell rm /system/bin/app_process.wrap
2103cab2bb3Spatrick      adb_shell rm /system/bin/asanwrapper
2113cab2bb3Spatrick      adb_shell rm /system/bin/app_process
2123cab2bb3Spatrick      adb_shell ln -s /system/bin/app_process32 /system/bin/app_process
2133cab2bb3Spatrick    fi
2143cab2bb3Spatrick
2153cab2bb3Spatrick    if [[ ANDROID_O -eq 1 ]]; then
2163cab2bb3Spatrick      adb_shell mv /system/etc/ld.config.txt.saved /system/etc/ld.config.txt
2173cab2bb3Spatrick    fi
2183cab2bb3Spatrick
2193cab2bb3Spatrick    echo '>> Restarting shell'
2203cab2bb3Spatrick    adb_shell stop
2213cab2bb3Spatrick    adb_shell start
2223cab2bb3Spatrick
2233cab2bb3Spatrick    # Remove the library on the last step to give a chance to the 'su' binary to
2243cab2bb3Spatrick    # be executed without problem.
2253cab2bb3Spatrick    adb_shell rm /system/lib/$ASAN_RT
2263cab2bb3Spatrick
2273cab2bb3Spatrick    echo '>> Done'
2283cab2bb3Spatrick    exit 0
2293cab2bb3Spatrickfi
2303cab2bb3Spatrick
2313cab2bb3Spatrickif [[ -d "$lib" ]]; then
2323cab2bb3Spatrick    ASAN_RT_PATH="$lib"
2333cab2bb3Spatrickelif [[ -f "$lib" && "$lib" == *"$ASAN_RT" ]]; then
2343cab2bb3Spatrick    ASAN_RT_PATH=$(dirname "$lib")
2353cab2bb3Spatrickelif [[ -f "$HERE/$ASAN_RT" ]]; then
2363cab2bb3Spatrick    ASAN_RT_PATH="$HERE"
2373cab2bb3Spatrickelif [[ $(basename "$HERE") == "bin" ]]; then
2383cab2bb3Spatrick    # We could be in the toolchain's base directory.
2393cab2bb3Spatrick    # Consider ../lib, ../lib/asan, ../lib/linux,
2403cab2bb3Spatrick    # ../lib/clang/$VERSION/lib/linux, and ../lib64/clang/$VERSION/lib/linux.
2413cab2bb3Spatrick    P=$(ls "$HERE"/../lib/"$ASAN_RT" \
2423cab2bb3Spatrick           "$HERE"/../lib/asan/"$ASAN_RT" \
2433cab2bb3Spatrick           "$HERE"/../lib/linux/"$ASAN_RT" \
2443cab2bb3Spatrick           "$HERE"/../lib/clang/*/lib/linux/"$ASAN_RT" \
2453cab2bb3Spatrick           "$HERE"/../lib64/clang/*/lib/linux/"$ASAN_RT" 2>/dev/null | sort | tail -1)
2463cab2bb3Spatrick    if [[ -n "$P" ]]; then
2473cab2bb3Spatrick        ASAN_RT_PATH="$(dirname "$P")"
2483cab2bb3Spatrick    fi
2493cab2bb3Spatrickfi
2503cab2bb3Spatrick
2513cab2bb3Spatrickif [[ -z "$ASAN_RT_PATH" || ! -f "$ASAN_RT_PATH/$ASAN_RT" ]]; then
2523cab2bb3Spatrick    echo ">> ASan runtime library not found"
2533cab2bb3Spatrick    exit 1
2543cab2bb3Spatrickfi
2553cab2bb3Spatrick
2563cab2bb3Spatrickif [[ -n "$ASAN_RT64" ]]; then
2573cab2bb3Spatrick  if [[ -z "$ASAN_RT_PATH" || ! -f "$ASAN_RT_PATH/$ASAN_RT64" ]]; then
2583cab2bb3Spatrick    echo ">> ASan runtime library not found"
2593cab2bb3Spatrick    exit 1
2603cab2bb3Spatrick  fi
2613cab2bb3Spatrickfi
2623cab2bb3Spatrick
2633cab2bb3SpatrickTMPDIRBASE=$(mktemp -d)
2643cab2bb3SpatrickTMPDIROLD="$TMPDIRBASE/old"
2653cab2bb3SpatrickTMPDIR="$TMPDIRBASE/new"
2663cab2bb3Spatrickmkdir "$TMPDIROLD"
2673cab2bb3Spatrick
2683cab2bb3Spatrickif ! adb_shell ls -l /system/bin/app_process | grep -o '\->.*app_process' >&/dev/null; then
2693cab2bb3Spatrick
2703cab2bb3Spatrick    if adb_pull /system/bin/app_process.real /dev/null >&/dev/null; then
2713cab2bb3Spatrick        echo '>> Old-style ASan installation detected. Reverting.'
2723cab2bb3Spatrick        adb_shell mv /system/bin/app_process.real /system/bin/app_process
2733cab2bb3Spatrick    fi
2743cab2bb3Spatrick
2753cab2bb3Spatrick    echo '>> Pre-L device detected. Setting up app_process symlink.'
2763cab2bb3Spatrick    adb_shell mv /system/bin/app_process /system/bin/app_process32
2773cab2bb3Spatrick    adb_shell ln -s /system/bin/app_process32 /system/bin/app_process
2783cab2bb3Spatrickfi
2793cab2bb3Spatrick
2803cab2bb3Spatrickecho '>> Copying files from the device'
2813cab2bb3Spatrickif [[ -n "$ASAN_RT64" ]]; then
2823cab2bb3Spatrick  adb_pull /system/lib/"$ASAN_RT" "$TMPDIROLD" || true
2833cab2bb3Spatrick  adb_pull /system/lib64/"$ASAN_RT64" "$TMPDIROLD" || true
2843cab2bb3Spatrick  adb_pull /system/bin/app_process32 "$TMPDIROLD" || true
2853cab2bb3Spatrick  adb_pull /system/bin/app_process32.real "$TMPDIROLD" || true
2863cab2bb3Spatrick  adb_pull /system/bin/app_process64 "$TMPDIROLD" || true
2873cab2bb3Spatrick  adb_pull /system/bin/app_process64.real "$TMPDIROLD" || true
2883cab2bb3Spatrick  adb_pull /system/bin/asanwrapper "$TMPDIROLD" || true
2893cab2bb3Spatrick  adb_pull /system/bin/asanwrapper64 "$TMPDIROLD" || true
2903cab2bb3Spatrickelse
2913cab2bb3Spatrick  adb_pull /system/lib/"$ASAN_RT" "$TMPDIROLD" || true
2923cab2bb3Spatrick  adb_pull /system/bin/app_process32 "$TMPDIROLD" || true
2933cab2bb3Spatrick  adb_pull /system/bin/app_process.wrap "$TMPDIROLD" || true
2943cab2bb3Spatrick  adb_pull /system/bin/asanwrapper "$TMPDIROLD" || true
2953cab2bb3Spatrickfi
2963cab2bb3Spatrickcp -r "$TMPDIROLD" "$TMPDIR"
2973cab2bb3Spatrick
2983cab2bb3Spatrickif [[ -f "$TMPDIR/app_process.wrap" || -f "$TMPDIR/app_process64.real" ]]; then
2993cab2bb3Spatrick    echo ">> Previous installation detected"
3003cab2bb3Spatrickelse
3013cab2bb3Spatrick    echo ">> New installation"
3023cab2bb3Spatrickfi
3033cab2bb3Spatrick
3043cab2bb3Spatrickecho '>> Generating wrappers'
3053cab2bb3Spatrick
3063cab2bb3Spatrickcp "$ASAN_RT_PATH/$ASAN_RT" "$TMPDIR/"
3073cab2bb3Spatrickif [[ -n "$ASAN_RT64" ]]; then
3083cab2bb3Spatrick  cp "$ASAN_RT_PATH/$ASAN_RT64" "$TMPDIR/"
3093cab2bb3Spatrickfi
3103cab2bb3Spatrick
3113cab2bb3SpatrickASAN_OPTIONS=start_deactivated=1
3123cab2bb3Spatrick
3133cab2bb3Spatrick# The name of a symlink to libclang_rt.asan-$ARCH-android.so used in LD_PRELOAD.
3143cab2bb3Spatrick# The idea is to have the same name in lib and lib64 to keep it from falling
3153cab2bb3Spatrick# apart when a 64-bit process spawns a 32-bit one, inheriting the environment.
3163cab2bb3SpatrickASAN_RT_SYMLINK=symlink-to-libclang_rt.asan
3173cab2bb3Spatrick
3183cab2bb3Spatrickfunction generate_zygote_wrapper { # from, to
3193cab2bb3Spatrick  local _from=$1
3203cab2bb3Spatrick  local _to=$2
3213cab2bb3Spatrick  if [[ PRE_L -eq 0 ]]; then
3223cab2bb3Spatrick    # LD_PRELOAD parsing is broken in N if it starts with ":". Luckily, it is
3233cab2bb3Spatrick    # unset in the system environment since L.
3243cab2bb3Spatrick    local _ld_preload=$ASAN_RT_SYMLINK
3253cab2bb3Spatrick  else
3263cab2bb3Spatrick    local _ld_preload=\$LD_PRELOAD:$ASAN_RT_SYMLINK
3273cab2bb3Spatrick  fi
3283cab2bb3Spatrick  cat <<EOF >"$TMPDIR/$_from"
3293cab2bb3Spatrick#!/system/bin/sh-from-zygote
3303cab2bb3SpatrickASAN_OPTIONS=$ASAN_OPTIONS \\
3313cab2bb3SpatrickASAN_ACTIVATION_OPTIONS=include_if_exists=/data/local/tmp/asan.options.%b \\
3323cab2bb3SpatrickLD_PRELOAD=$_ld_preload \\
333d89ec533Spatrickexec $_to "\$@"
3343cab2bb3Spatrick
3353cab2bb3SpatrickEOF
3363cab2bb3Spatrick}
3373cab2bb3Spatrick
3383cab2bb3Spatrick# On Android-L not allowing user segv handler breaks some applications.
3393cab2bb3Spatrick# Since ~May 2017 this is the default setting; included for compatibility with
3403cab2bb3Spatrick# older library versions.
3413cab2bb3Spatrickif [[ PRE_L -eq 0 ]]; then
3423cab2bb3Spatrick    ASAN_OPTIONS="$ASAN_OPTIONS,allow_user_segv_handler=1"
3433cab2bb3Spatrickfi
3443cab2bb3Spatrick
3453cab2bb3Spatrickif [[ x$extra_options != x ]] ; then
3463cab2bb3Spatrick    ASAN_OPTIONS="$ASAN_OPTIONS,$extra_options"
3473cab2bb3Spatrickfi
3483cab2bb3Spatrick
3493cab2bb3Spatrick# Zygote wrapper.
3503cab2bb3Spatrickif [[ -f "$TMPDIR/app_process64" ]]; then
3513cab2bb3Spatrick  # A 64-bit device.
3523cab2bb3Spatrick  if [[ ! -f "$TMPDIR/app_process64.real" ]]; then
3533cab2bb3Spatrick    # New installation.
3543cab2bb3Spatrick    mv "$TMPDIR/app_process32" "$TMPDIR/app_process32.real"
3553cab2bb3Spatrick    mv "$TMPDIR/app_process64" "$TMPDIR/app_process64.real"
3563cab2bb3Spatrick  fi
3573cab2bb3Spatrick  generate_zygote_wrapper "app_process32" "/system/bin/app_process32.real"
3583cab2bb3Spatrick  generate_zygote_wrapper "app_process64" "/system/bin/app_process64.real"
3593cab2bb3Spatrickelse
3603cab2bb3Spatrick  # A 32-bit device.
3613cab2bb3Spatrick  generate_zygote_wrapper "app_process.wrap" "/system/bin/app_process32"
3623cab2bb3Spatrickfi
3633cab2bb3Spatrick
3643cab2bb3Spatrick# General command-line tool wrapper (use for anything that's not started as
3653cab2bb3Spatrick# zygote).
3663cab2bb3Spatrickcat <<EOF >"$TMPDIR/asanwrapper"
3673cab2bb3Spatrick#!/system/bin/sh
3683cab2bb3SpatrickLD_PRELOAD=$ASAN_RT_SYMLINK \\
3693cab2bb3Spatrickexec \$@
3703cab2bb3Spatrick
3713cab2bb3SpatrickEOF
3723cab2bb3Spatrick
3733cab2bb3Spatrickif [[ -n "$ASAN_RT64" ]]; then
3743cab2bb3Spatrick  cat <<EOF >"$TMPDIR/asanwrapper64"
3753cab2bb3Spatrick#!/system/bin/sh
3763cab2bb3SpatrickLD_PRELOAD=$ASAN_RT_SYMLINK \\
3773cab2bb3Spatrickexec \$@
3783cab2bb3Spatrick
3793cab2bb3SpatrickEOF
3803cab2bb3Spatrickfi
3813cab2bb3Spatrick
3823cab2bb3Spatrickfunction install { # from, to, chmod, chcon
3833cab2bb3Spatrick  local _from=$1
3843cab2bb3Spatrick  local _to=$2
3853cab2bb3Spatrick  local _mode=$3
3863cab2bb3Spatrick  local _context=$4
3873cab2bb3Spatrick  local _basename="$(basename "$_from")"
3883cab2bb3Spatrick  echo "Installing $_to/$_basename $_mode $_context"
3893cab2bb3Spatrick  adb_push "$_from" "$_to/$_basename"
3903cab2bb3Spatrick  adb_shell chown root.shell "$_to/$_basename"
3913cab2bb3Spatrick  if [[ -n "$_mode" ]]; then
3923cab2bb3Spatrick    adb_shell chmod "$_mode" "$_to/$_basename"
3933cab2bb3Spatrick  fi
3943cab2bb3Spatrick  if [[ -n "$_context" ]]; then
3953cab2bb3Spatrick    adb_shell chcon "$_context" "$_to/$_basename"
3963cab2bb3Spatrick  fi
3973cab2bb3Spatrick}
3983cab2bb3Spatrick
3993cab2bb3Spatrickif ! ( cd "$TMPDIRBASE" && diff -qr old/ new/ ) ; then
4003cab2bb3Spatrick    # Make SELinux happy by keeping app_process wrapper and the shell
4013cab2bb3Spatrick    # it runs on in zygote domain.
4023cab2bb3Spatrick    ENFORCING=0
4033cab2bb3Spatrick    if adb_shell getenforce | grep Enforcing >/dev/null; then
4043cab2bb3Spatrick        # Sometimes shell is not allowed to change file contexts.
4053cab2bb3Spatrick        # Temporarily switch to permissive.
4063cab2bb3Spatrick        ENFORCING=1
4073cab2bb3Spatrick        adb_shell setenforce 0
4083cab2bb3Spatrick    fi
4093cab2bb3Spatrick
4103cab2bb3Spatrick    if [[ PRE_L -eq 1 ]]; then
4113cab2bb3Spatrick        CTX=u:object_r:system_file:s0
4123cab2bb3Spatrick    else
4133cab2bb3Spatrick        CTX=u:object_r:zygote_exec:s0
4143cab2bb3Spatrick    fi
4153cab2bb3Spatrick
4163cab2bb3Spatrick    echo '>> Pushing files to the device'
4173cab2bb3Spatrick
4183cab2bb3Spatrick    if [[ -n "$ASAN_RT64" ]]; then
4193cab2bb3Spatrick      install "$TMPDIR/$ASAN_RT" /system/lib 644
4203cab2bb3Spatrick      install "$TMPDIR/$ASAN_RT64" /system/lib64 644
4213cab2bb3Spatrick      install "$TMPDIR/app_process32" /system/bin 755 $CTX
4223cab2bb3Spatrick      install "$TMPDIR/app_process32.real" /system/bin 755 $CTX
4233cab2bb3Spatrick      install "$TMPDIR/app_process64" /system/bin 755 $CTX
4243cab2bb3Spatrick      install "$TMPDIR/app_process64.real" /system/bin 755 $CTX
4253cab2bb3Spatrick      install "$TMPDIR/asanwrapper" /system/bin 755
4263cab2bb3Spatrick      install "$TMPDIR/asanwrapper64" /system/bin 755
4273cab2bb3Spatrick
4283cab2bb3Spatrick      adb_shell rm -f /system/lib/$ASAN_RT_SYMLINK
4293cab2bb3Spatrick      adb_shell ln -s $ASAN_RT /system/lib/$ASAN_RT_SYMLINK
4303cab2bb3Spatrick      adb_shell rm -f /system/lib64/$ASAN_RT_SYMLINK
4313cab2bb3Spatrick      adb_shell ln -s $ASAN_RT64 /system/lib64/$ASAN_RT_SYMLINK
4323cab2bb3Spatrick    else
4333cab2bb3Spatrick      install "$TMPDIR/$ASAN_RT" /system/lib 644
4343cab2bb3Spatrick      install "$TMPDIR/app_process32" /system/bin 755 $CTX
4353cab2bb3Spatrick      install "$TMPDIR/app_process.wrap" /system/bin 755 $CTX
4363cab2bb3Spatrick      install "$TMPDIR/asanwrapper" /system/bin 755 $CTX
4373cab2bb3Spatrick
4383cab2bb3Spatrick      adb_shell rm -f /system/lib/$ASAN_RT_SYMLINK
4393cab2bb3Spatrick      adb_shell ln -s $ASAN_RT /system/lib/$ASAN_RT_SYMLINK
4403cab2bb3Spatrick
4413cab2bb3Spatrick      adb_shell rm /system/bin/app_process
4423cab2bb3Spatrick      adb_shell ln -s /system/bin/app_process.wrap /system/bin/app_process
4433cab2bb3Spatrick    fi
4443cab2bb3Spatrick
4453cab2bb3Spatrick    adb_shell cp /system/bin/sh /system/bin/sh-from-zygote
4463cab2bb3Spatrick    adb_shell chcon $CTX /system/bin/sh-from-zygote
4473cab2bb3Spatrick
4483cab2bb3Spatrick    if [[ ANDROID_O -eq 1 ]]; then
4493cab2bb3Spatrick      # For Android O, the linker namespace is temporarily disabled.
4503cab2bb3Spatrick      adb_shell mv /system/etc/ld.config.txt /system/etc/ld.config.txt.saved
4513cab2bb3Spatrick    fi
4523cab2bb3Spatrick
4533cab2bb3Spatrick    if [ $ENFORCING == 1 ]; then
4543cab2bb3Spatrick        adb_shell setenforce 1
4553cab2bb3Spatrick    fi
4563cab2bb3Spatrick
4573cab2bb3Spatrick    echo '>> Restarting shell (asynchronous)'
4583cab2bb3Spatrick    adb_shell stop
4593cab2bb3Spatrick    adb_shell start
4603cab2bb3Spatrick
4613cab2bb3Spatrick    echo '>> Please wait until the device restarts'
4623cab2bb3Spatrickelse
4633cab2bb3Spatrick    echo '>> Device is up to date'
4643cab2bb3Spatrickfi
4653cab2bb3Spatrick
4663cab2bb3Spatrickrm -r "$TMPDIRBASE"
467