xref: /llvm-project/compiler-rt/lib/asan/scripts/asan_device_setup (revision 626e2a6c6236d2fd7582928a0363d381c55eb43d)
1*626e2a6cSFrederic Cambus#!/usr/bin/env bash
284610ed7SEvgeniy Stepanov#===- lib/asan/scripts/asan_device_setup -----------------------------------===#
384610ed7SEvgeniy Stepanov#
42946cd70SChandler Carruth# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
52946cd70SChandler Carruth# See https://llvm.org/LICENSE.txt for license information.
62946cd70SChandler Carruth# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
784610ed7SEvgeniy Stepanov#
884610ed7SEvgeniy Stepanov# Prepare Android device to run ASan applications.
984610ed7SEvgeniy Stepanov#
1084610ed7SEvgeniy Stepanov#===------------------------------------------------------------------------===#
1184610ed7SEvgeniy Stepanov
120b9109c8SEvgeniy Stepanovset -e
1384610ed7SEvgeniy Stepanov
1484610ed7SEvgeniy StepanovHERE="$(cd "$(dirname "$0")" && pwd)"
1584610ed7SEvgeniy Stepanov
1684610ed7SEvgeniy Stepanovrevert=no
1784610ed7SEvgeniy Stepanovextra_options=
1884610ed7SEvgeniy Stepanovdevice=
1984610ed7SEvgeniy Stepanovlib=
2084d30ba4SEvgeniy Stepanovuse_su=0
2184610ed7SEvgeniy Stepanov
2284610ed7SEvgeniy Stepanovfunction usage {
233ff723f3SEvgeniy Stepanov    echo "usage: $0 [--revert] [--device device-id] [--lib path] [--extra-options options]"
2484610ed7SEvgeniy Stepanov    echo "  --revert: Uninstall ASan from the device."
2584610ed7SEvgeniy Stepanov    echo "  --lib: Path to ASan runtime library."
263ff723f3SEvgeniy Stepanov    echo "  --extra-options: Extra ASAN_OPTIONS."
2784610ed7SEvgeniy Stepanov    echo "  --device: Install to the given device. Use 'adb devices' to find"
2884610ed7SEvgeniy Stepanov    echo "            device-id."
2984d30ba4SEvgeniy Stepanov    echo "  --use-su: Use 'su -c' prefix for every adb command instead of using"
3084d30ba4SEvgeniy Stepanov    echo "            'adb root' once."
3184610ed7SEvgeniy Stepanov    echo
3284610ed7SEvgeniy Stepanov    exit 1
3384610ed7SEvgeniy Stepanov}
3484610ed7SEvgeniy Stepanov
3584d30ba4SEvgeniy Stepanovfunction adb_push {
3684d30ba4SEvgeniy Stepanov  if [ $use_su -eq 0 ]; then
3784d30ba4SEvgeniy Stepanov    $ADB push "$1" "$2"
3884d30ba4SEvgeniy Stepanov  else
3984d30ba4SEvgeniy Stepanov    local FILENAME=$(basename $1)
4084d30ba4SEvgeniy Stepanov    $ADB push "$1" "/data/local/tmp/$FILENAME"
4184d30ba4SEvgeniy Stepanov    $ADB shell su -c "rm \\\"$2/$FILENAME\\\"" >&/dev/null
4284d30ba4SEvgeniy Stepanov    $ADB shell su -c "cat \\\"/data/local/tmp/$FILENAME\\\" > \\\"$2/$FILENAME\\\""
4384d30ba4SEvgeniy Stepanov    $ADB shell su -c "rm \\\"/data/local/tmp/$FILENAME\\\""
4484d30ba4SEvgeniy Stepanov  fi
4584d30ba4SEvgeniy Stepanov}
4684d30ba4SEvgeniy Stepanov
4784d30ba4SEvgeniy Stepanovfunction adb_remount {
4884d30ba4SEvgeniy Stepanov  if [ $use_su -eq 0 ]; then
4984d30ba4SEvgeniy Stepanov    $ADB remount
5084d30ba4SEvgeniy Stepanov  else
5184d30ba4SEvgeniy Stepanov    local STORAGE=`$ADB shell mount | grep /system | cut -d ' ' -f1`
5284d30ba4SEvgeniy Stepanov    if [ "$STORAGE" != "" ]; then
5384d30ba4SEvgeniy Stepanov      echo Remounting $STORAGE at /system
54b76e4d12SEvgeniy Stepanov      $ADB shell su -c "mount -o rw,remount $STORAGE /system"
5584d30ba4SEvgeniy Stepanov    else
5684d30ba4SEvgeniy Stepanov      echo Failed to get storage device name for "/system" mount point
5784d30ba4SEvgeniy Stepanov    fi
5884d30ba4SEvgeniy Stepanov  fi
5984d30ba4SEvgeniy Stepanov}
6084d30ba4SEvgeniy Stepanov
6184d30ba4SEvgeniy Stepanovfunction adb_shell {
6284d30ba4SEvgeniy Stepanov  if [ $use_su -eq 0 ]; then
6384d30ba4SEvgeniy Stepanov    $ADB shell $@
6484d30ba4SEvgeniy Stepanov  else
6584d30ba4SEvgeniy Stepanov    $ADB shell su -c "$*"
6684d30ba4SEvgeniy Stepanov  fi
6784d30ba4SEvgeniy Stepanov}
6884d30ba4SEvgeniy Stepanov
6984d30ba4SEvgeniy Stepanovfunction adb_root {
7084d30ba4SEvgeniy Stepanov  if [ $use_su -eq 0 ]; then
7184d30ba4SEvgeniy Stepanov    $ADB root
7284d30ba4SEvgeniy Stepanov  fi
7384d30ba4SEvgeniy Stepanov}
7484d30ba4SEvgeniy Stepanov
7584d30ba4SEvgeniy Stepanovfunction adb_wait_for_device {
7684d30ba4SEvgeniy Stepanov  $ADB wait-for-device
7784d30ba4SEvgeniy Stepanov}
7884d30ba4SEvgeniy Stepanov
7984d30ba4SEvgeniy Stepanovfunction adb_pull {
8084d30ba4SEvgeniy Stepanov  if [ $use_su -eq 0 ]; then
8184d30ba4SEvgeniy Stepanov    $ADB pull "$1" "$2"
8284d30ba4SEvgeniy Stepanov  else
8384d30ba4SEvgeniy Stepanov    local FILENAME=$(basename $1)
8484d30ba4SEvgeniy Stepanov    $ADB shell rm "/data/local/tmp/$FILENAME" >&/dev/null
8584d30ba4SEvgeniy Stepanov    $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\\\"" &&
8684d30ba4SEvgeniy Stepanov    $ADB pull "/data/local/tmp/$FILENAME" "$2" >&/dev/null && $ADB shell "rm \"/data/local/tmp/$FILENAME\""
8784d30ba4SEvgeniy Stepanov  fi
8884d30ba4SEvgeniy Stepanov}
8984d30ba4SEvgeniy Stepanov
90df5ba147SEvgeniy Stepanovfunction get_device_arch { # OUT OUT64
910b9109c8SEvgeniy Stepanov    local _outvar=$1
92df5ba147SEvgeniy Stepanov    local _outvar64=$2
9384d30ba4SEvgeniy Stepanov    local _ABI=$(adb_shell getprop ro.product.cpu.abi)
940b9109c8SEvgeniy Stepanov    local _ARCH=
95df5ba147SEvgeniy Stepanov    local _ARCH64=
960b9109c8SEvgeniy Stepanov    if [[ $_ABI == x86* ]]; then
97fbb9132eSEvgenii Stepanov        _ARCH=i686
980b9109c8SEvgeniy Stepanov    elif [[ $_ABI == armeabi* ]]; then
990b9109c8SEvgeniy Stepanov        _ARCH=arm
100df5ba147SEvgeniy Stepanov    elif [[ $_ABI == arm64-v8a* ]]; then
101df5ba147SEvgeniy Stepanov        _ARCH=arm
102df5ba147SEvgeniy Stepanov        _ARCH64=aarch64
1030b9109c8SEvgeniy Stepanov    else
1040b9109c8SEvgeniy Stepanov        echo "Unrecognized device ABI: $_ABI"
1050b9109c8SEvgeniy Stepanov        exit 1
1060b9109c8SEvgeniy Stepanov    fi
1070b9109c8SEvgeniy Stepanov    eval $_outvar=\$_ARCH
108df5ba147SEvgeniy Stepanov    eval $_outvar64=\$_ARCH64
1090b9109c8SEvgeniy Stepanov}
1100b9109c8SEvgeniy Stepanov
11184610ed7SEvgeniy Stepanovwhile [[ $# > 0 ]]; do
11284610ed7SEvgeniy Stepanov  case $1 in
11384610ed7SEvgeniy Stepanov    --revert)
11484610ed7SEvgeniy Stepanov      revert=yes
11584610ed7SEvgeniy Stepanov      ;;
11684610ed7SEvgeniy Stepanov    --extra-options)
11784610ed7SEvgeniy Stepanov      shift
11884610ed7SEvgeniy Stepanov      if [[ $# == 0 ]]; then
11984610ed7SEvgeniy Stepanov        echo "--extra-options requires an argument."
12084610ed7SEvgeniy Stepanov        exit 1
12184610ed7SEvgeniy Stepanov      fi
12284610ed7SEvgeniy Stepanov      extra_options="$1"
12384610ed7SEvgeniy Stepanov      ;;
12484610ed7SEvgeniy Stepanov    --lib)
12584610ed7SEvgeniy Stepanov      shift
12684610ed7SEvgeniy Stepanov      if [[ $# == 0 ]]; then
12784610ed7SEvgeniy Stepanov        echo "--lib requires an argument."
12884610ed7SEvgeniy Stepanov        exit 1
12984610ed7SEvgeniy Stepanov      fi
13084610ed7SEvgeniy Stepanov      lib="$1"
13184610ed7SEvgeniy Stepanov      ;;
13284610ed7SEvgeniy Stepanov    --device)
13384610ed7SEvgeniy Stepanov      shift
13484610ed7SEvgeniy Stepanov      if [[ $# == 0 ]]; then
13584610ed7SEvgeniy Stepanov        echo "--device requires an argument."
13684610ed7SEvgeniy Stepanov        exit 1
13784610ed7SEvgeniy Stepanov      fi
13884610ed7SEvgeniy Stepanov      device="$1"
13984610ed7SEvgeniy Stepanov      ;;
14084d30ba4SEvgeniy Stepanov    --use-su)
14184d30ba4SEvgeniy Stepanov      use_su=1
14284d30ba4SEvgeniy Stepanov      ;;
14384610ed7SEvgeniy Stepanov    *)
14484610ed7SEvgeniy Stepanov      usage
14584610ed7SEvgeniy Stepanov      ;;
14684610ed7SEvgeniy Stepanov  esac
14784610ed7SEvgeniy Stepanov  shift
14884610ed7SEvgeniy Stepanovdone
14984610ed7SEvgeniy Stepanov
15084610ed7SEvgeniy StepanovADB=${ADB:-adb}
15184610ed7SEvgeniy Stepanovif [[ x$device != x ]]; then
15284610ed7SEvgeniy Stepanov    ADB="$ADB -s $device"
15384610ed7SEvgeniy Stepanovfi
15484610ed7SEvgeniy Stepanov
15584d30ba4SEvgeniy Stepanovif [ $use_su -eq 1 ]; then
15684d30ba4SEvgeniy Stepanov  # Test if 'su' is present on the device
15784d30ba4SEvgeniy Stepanov  SU_TEST_OUT=`$ADB shell su -c "echo foo" 2>&1 | sed 's/\r$//'`
15884d30ba4SEvgeniy Stepanov  if [ $? != 0 -o "$SU_TEST_OUT" != "foo" ]; then
15984d30ba4SEvgeniy Stepanov    echo "ERROR: Cannot use 'su -c':"
16084d30ba4SEvgeniy Stepanov    echo "$ adb shell su -c \"echo foo\""
16184d30ba4SEvgeniy Stepanov    echo $SU_TEST_OUT
16284d30ba4SEvgeniy Stepanov    echo "Check that 'su' binary is correctly installed on the device or omit"
16384d30ba4SEvgeniy Stepanov    echo "            --use-su flag"
16484d30ba4SEvgeniy Stepanov    exit 1
16584d30ba4SEvgeniy Stepanov  fi
16684d30ba4SEvgeniy Stepanovfi
16784d30ba4SEvgeniy Stepanov
1680b9109c8SEvgeniy Stepanovecho '>> Remounting /system rw'
16984d30ba4SEvgeniy Stepanovadb_wait_for_device
17084d30ba4SEvgeniy Stepanovadb_root
17184d30ba4SEvgeniy Stepanovadb_wait_for_device
17284d30ba4SEvgeniy Stepanovadb_remount
17384d30ba4SEvgeniy Stepanovadb_wait_for_device
17421202ba8SEvgeniy Stepanov
175df5ba147SEvgeniy Stepanovget_device_arch ARCH ARCH64
176faef7748SEvgeniy Stepanovecho "Target architecture: $ARCH"
1770b9109c8SEvgeniy StepanovASAN_RT="libclang_rt.asan-$ARCH-android.so"
178df5ba147SEvgeniy Stepanovif [[ -n $ARCH64 ]]; then
179df5ba147SEvgeniy Stepanov  echo "Target architecture: $ARCH64"
180df5ba147SEvgeniy Stepanov  ASAN_RT64="libclang_rt.asan-$ARCH64-android.so"
181df5ba147SEvgeniy Stepanovfi
1820b9109c8SEvgeniy Stepanov
18329c74871SEvgeniy StepanovRELEASE=$(adb_shell getprop ro.build.version.release)
18429c74871SEvgeniy StepanovPRE_L=0
18529c74871SEvgeniy Stepanovif echo "$RELEASE" | grep '^4\.' >&/dev/null; then
18629c74871SEvgeniy Stepanov    PRE_L=1
18729c74871SEvgeniy Stepanovfi
18829c74871SEvgeniy StepanovANDROID_O=0
18929c74871SEvgeniy Stepanovif echo "$RELEASE" | grep '^8\.0\.' >&/dev/null; then
19029c74871SEvgeniy Stepanov    # 8.0.x is for Android O
19129c74871SEvgeniy Stepanov    ANDROID_O=1
19229c74871SEvgeniy Stepanovfi
19329c74871SEvgeniy Stepanov
1940b9109c8SEvgeniy Stepanovif [[ x$revert == xyes ]]; then
1950b9109c8SEvgeniy Stepanov    echo '>> Uninstalling ASan'
1960b9109c8SEvgeniy Stepanov
19784d30ba4SEvgeniy Stepanov    if ! adb_shell ls -l /system/bin/app_process | grep -o '\->.*app_process' >&/dev/null; then
19821202ba8SEvgeniy Stepanov      echo '>> Pre-L device detected.'
19984d30ba4SEvgeniy Stepanov      adb_shell mv /system/bin/app_process.real /system/bin/app_process
20084d30ba4SEvgeniy Stepanov      adb_shell rm /system/bin/asanwrapper
201df5ba147SEvgeniy Stepanov    elif ! adb_shell ls -l /system/bin/app_process64.real | grep -o 'No such file or directory' >&/dev/null; then
202df5ba147SEvgeniy Stepanov      # 64-bit installation.
203df5ba147SEvgeniy Stepanov      adb_shell mv /system/bin/app_process32.real /system/bin/app_process32
204df5ba147SEvgeniy Stepanov      adb_shell mv /system/bin/app_process64.real /system/bin/app_process64
205df5ba147SEvgeniy Stepanov      adb_shell rm /system/bin/asanwrapper
206df5ba147SEvgeniy Stepanov      adb_shell rm /system/bin/asanwrapper64
20721202ba8SEvgeniy Stepanov    else
208df5ba147SEvgeniy Stepanov      # 32-bit installation.
20984d30ba4SEvgeniy Stepanov      adb_shell rm /system/bin/app_process.wrap
21084d30ba4SEvgeniy Stepanov      adb_shell rm /system/bin/asanwrapper
21184d30ba4SEvgeniy Stepanov      adb_shell rm /system/bin/app_process
21284d30ba4SEvgeniy Stepanov      adb_shell ln -s /system/bin/app_process32 /system/bin/app_process
21321202ba8SEvgeniy Stepanov    fi
21484610ed7SEvgeniy Stepanov
21529c74871SEvgeniy Stepanov    if [[ ANDROID_O -eq 1 ]]; then
21629c74871SEvgeniy Stepanov      adb_shell mv /system/etc/ld.config.txt.saved /system/etc/ld.config.txt
21729c74871SEvgeniy Stepanov    fi
21829c74871SEvgeniy Stepanov
21984610ed7SEvgeniy Stepanov    echo '>> Restarting shell'
22084d30ba4SEvgeniy Stepanov    adb_shell stop
22184d30ba4SEvgeniy Stepanov    adb_shell start
22284d30ba4SEvgeniy Stepanov
22384d30ba4SEvgeniy Stepanov    # Remove the library on the last step to give a chance to the 'su' binary to
22484d30ba4SEvgeniy Stepanov    # be executed without problem.
22584d30ba4SEvgeniy Stepanov    adb_shell rm /system/lib/$ASAN_RT
22684610ed7SEvgeniy Stepanov
22784610ed7SEvgeniy Stepanov    echo '>> Done'
22884610ed7SEvgeniy Stepanov    exit 0
22984610ed7SEvgeniy Stepanovfi
23084610ed7SEvgeniy Stepanov
23184610ed7SEvgeniy Stepanovif [[ -d "$lib" ]]; then
23284610ed7SEvgeniy Stepanov    ASAN_RT_PATH="$lib"
23384610ed7SEvgeniy Stepanovelif [[ -f "$lib" && "$lib" == *"$ASAN_RT" ]]; then
23484610ed7SEvgeniy Stepanov    ASAN_RT_PATH=$(dirname "$lib")
23584610ed7SEvgeniy Stepanovelif [[ -f "$HERE/$ASAN_RT" ]]; then
23684610ed7SEvgeniy Stepanov    ASAN_RT_PATH="$HERE"
23784610ed7SEvgeniy Stepanovelif [[ $(basename "$HERE") == "bin" ]]; then
23884610ed7SEvgeniy Stepanov    # We could be in the toolchain's base directory.
239c8bdae10SDan Albert    # Consider ../lib, ../lib/asan, ../lib/linux,
240c8bdae10SDan Albert    # ../lib/clang/$VERSION/lib/linux, and ../lib64/clang/$VERSION/lib/linux.
241c8bdae10SDan Albert    P=$(ls "$HERE"/../lib/"$ASAN_RT" \
242c8bdae10SDan Albert           "$HERE"/../lib/asan/"$ASAN_RT" \
243c8bdae10SDan Albert           "$HERE"/../lib/linux/"$ASAN_RT" \
244c8bdae10SDan Albert           "$HERE"/../lib/clang/*/lib/linux/"$ASAN_RT" \
245c8bdae10SDan Albert           "$HERE"/../lib64/clang/*/lib/linux/"$ASAN_RT" 2>/dev/null | sort | tail -1)
24684610ed7SEvgeniy Stepanov    if [[ -n "$P" ]]; then
24784610ed7SEvgeniy Stepanov        ASAN_RT_PATH="$(dirname "$P")"
24884610ed7SEvgeniy Stepanov    fi
24984610ed7SEvgeniy Stepanovfi
25084610ed7SEvgeniy Stepanov
25184610ed7SEvgeniy Stepanovif [[ -z "$ASAN_RT_PATH" || ! -f "$ASAN_RT_PATH/$ASAN_RT" ]]; then
25221202ba8SEvgeniy Stepanov    echo ">> ASan runtime library not found"
25384610ed7SEvgeniy Stepanov    exit 1
25484610ed7SEvgeniy Stepanovfi
25584610ed7SEvgeniy Stepanov
256df5ba147SEvgeniy Stepanovif [[ -n "$ASAN_RT64" ]]; then
257df5ba147SEvgeniy Stepanov  if [[ -z "$ASAN_RT_PATH" || ! -f "$ASAN_RT_PATH/$ASAN_RT64" ]]; then
258df5ba147SEvgeniy Stepanov    echo ">> ASan runtime library not found"
259df5ba147SEvgeniy Stepanov    exit 1
260df5ba147SEvgeniy Stepanov  fi
261df5ba147SEvgeniy Stepanovfi
262df5ba147SEvgeniy Stepanov
26384610ed7SEvgeniy StepanovTMPDIRBASE=$(mktemp -d)
26484610ed7SEvgeniy StepanovTMPDIROLD="$TMPDIRBASE/old"
26584610ed7SEvgeniy StepanovTMPDIR="$TMPDIRBASE/new"
26684610ed7SEvgeniy Stepanovmkdir "$TMPDIROLD"
26784610ed7SEvgeniy Stepanov
26884d30ba4SEvgeniy Stepanovif ! adb_shell ls -l /system/bin/app_process | grep -o '\->.*app_process' >&/dev/null; then
26921202ba8SEvgeniy Stepanov
27084d30ba4SEvgeniy Stepanov    if adb_pull /system/bin/app_process.real /dev/null >&/dev/null; then
27121202ba8SEvgeniy Stepanov        echo '>> Old-style ASan installation detected. Reverting.'
27284d30ba4SEvgeniy Stepanov        adb_shell mv /system/bin/app_process.real /system/bin/app_process
27321202ba8SEvgeniy Stepanov    fi
27421202ba8SEvgeniy Stepanov
27521202ba8SEvgeniy Stepanov    echo '>> Pre-L device detected. Setting up app_process symlink.'
27684d30ba4SEvgeniy Stepanov    adb_shell mv /system/bin/app_process /system/bin/app_process32
27784d30ba4SEvgeniy Stepanov    adb_shell ln -s /system/bin/app_process32 /system/bin/app_process
27821202ba8SEvgeniy Stepanovfi
27921202ba8SEvgeniy Stepanov
28084610ed7SEvgeniy Stepanovecho '>> Copying files from the device'
281df5ba147SEvgeniy Stepanovif [[ -n "$ASAN_RT64" ]]; then
282df5ba147SEvgeniy Stepanov  adb_pull /system/lib/"$ASAN_RT" "$TMPDIROLD" || true
283df5ba147SEvgeniy Stepanov  adb_pull /system/lib64/"$ASAN_RT64" "$TMPDIROLD" || true
284df5ba147SEvgeniy Stepanov  adb_pull /system/bin/app_process32 "$TMPDIROLD" || true
285df5ba147SEvgeniy Stepanov  adb_pull /system/bin/app_process32.real "$TMPDIROLD" || true
286df5ba147SEvgeniy Stepanov  adb_pull /system/bin/app_process64 "$TMPDIROLD" || true
287df5ba147SEvgeniy Stepanov  adb_pull /system/bin/app_process64.real "$TMPDIROLD" || true
288df5ba147SEvgeniy Stepanov  adb_pull /system/bin/asanwrapper "$TMPDIROLD" || true
289df5ba147SEvgeniy Stepanov  adb_pull /system/bin/asanwrapper64 "$TMPDIROLD" || true
290df5ba147SEvgeniy Stepanovelse
291df5ba147SEvgeniy Stepanov  adb_pull /system/lib/"$ASAN_RT" "$TMPDIROLD" || true
2922253d1c0SEvgeniy Stepanov  adb_pull /system/bin/app_process32 "$TMPDIROLD" || true
29384d30ba4SEvgeniy Stepanov  adb_pull /system/bin/app_process.wrap "$TMPDIROLD" || true
29484d30ba4SEvgeniy Stepanov  adb_pull /system/bin/asanwrapper "$TMPDIROLD" || true
295df5ba147SEvgeniy Stepanovfi
29684610ed7SEvgeniy Stepanovcp -r "$TMPDIROLD" "$TMPDIR"
29784610ed7SEvgeniy Stepanov
298df5ba147SEvgeniy Stepanovif [[ -f "$TMPDIR/app_process.wrap" || -f "$TMPDIR/app_process64.real" ]]; then
29921202ba8SEvgeniy Stepanov    echo ">> Previous installation detected"
30084610ed7SEvgeniy Stepanovelse
30121202ba8SEvgeniy Stepanov    echo ">> New installation"
30284610ed7SEvgeniy Stepanovfi
30384610ed7SEvgeniy Stepanov
30484610ed7SEvgeniy Stepanovecho '>> Generating wrappers'
30584610ed7SEvgeniy Stepanov
30684610ed7SEvgeniy Stepanovcp "$ASAN_RT_PATH/$ASAN_RT" "$TMPDIR/"
307df5ba147SEvgeniy Stepanovif [[ -n "$ASAN_RT64" ]]; then
308df5ba147SEvgeniy Stepanov  cp "$ASAN_RT_PATH/$ASAN_RT64" "$TMPDIR/"
309df5ba147SEvgeniy Stepanovfi
31084610ed7SEvgeniy Stepanov
311366ea711SEvgeniy StepanovASAN_OPTIONS=start_deactivated=1
312df5ba147SEvgeniy Stepanov
31311d3b279SEvgeniy Stepanov# The name of a symlink to libclang_rt.asan-$ARCH-android.so used in LD_PRELOAD.
31411d3b279SEvgeniy Stepanov# The idea is to have the same name in lib and lib64 to keep it from falling
31511d3b279SEvgeniy Stepanov# apart when a 64-bit process spawns a 32-bit one, inheriting the environment.
31611d3b279SEvgeniy StepanovASAN_RT_SYMLINK=symlink-to-libclang_rt.asan
31711d3b279SEvgeniy Stepanov
31811d3b279SEvgeniy Stepanovfunction generate_zygote_wrapper { # from, to
319df5ba147SEvgeniy Stepanov  local _from=$1
320df5ba147SEvgeniy Stepanov  local _to=$2
3217b6f275bSEvgeniy Stepanov  if [[ PRE_L -eq 0 ]]; then
3227b6f275bSEvgeniy Stepanov    # LD_PRELOAD parsing is broken in N if it starts with ":". Luckily, it is
3237b6f275bSEvgeniy Stepanov    # unset in the system environment since L.
32411d3b279SEvgeniy Stepanov    local _ld_preload=$ASAN_RT_SYMLINK
3257b6f275bSEvgeniy Stepanov  else
32611d3b279SEvgeniy Stepanov    local _ld_preload=\$LD_PRELOAD:$ASAN_RT_SYMLINK
3277b6f275bSEvgeniy Stepanov  fi
328df5ba147SEvgeniy Stepanov  cat <<EOF >"$TMPDIR/$_from"
329df5ba147SEvgeniy Stepanov#!/system/bin/sh-from-zygote
330df5ba147SEvgeniy StepanovASAN_OPTIONS=$ASAN_OPTIONS \\
331df5ba147SEvgeniy StepanovASAN_ACTIVATION_OPTIONS=include_if_exists=/data/local/tmp/asan.options.%b \\
3327b6f275bSEvgeniy StepanovLD_PRELOAD=$_ld_preload \\
333a305d250SAndrew Grieveexec $_to "\$@"
334df5ba147SEvgeniy Stepanov
335df5ba147SEvgeniy StepanovEOF
336df5ba147SEvgeniy Stepanov}
337a5d07482SEvgeniy Stepanov
3382db14a57SEvgeniy Stepanov# On Android-L not allowing user segv handler breaks some applications.
3392db14a57SEvgeniy Stepanov# Since ~May 2017 this is the default setting; included for compatibility with
3402db14a57SEvgeniy Stepanov# older library versions.
3412db14a57SEvgeniy Stepanovif [[ PRE_L -eq 0 ]]; then
3422db14a57SEvgeniy Stepanov    ASAN_OPTIONS="$ASAN_OPTIONS,allow_user_segv_handler=1"
3432db14a57SEvgeniy Stepanovfi
3442db14a57SEvgeniy Stepanov
34584610ed7SEvgeniy Stepanovif [[ x$extra_options != x ]] ; then
34684610ed7SEvgeniy Stepanov    ASAN_OPTIONS="$ASAN_OPTIONS,$extra_options"
34784610ed7SEvgeniy Stepanovfi
34884610ed7SEvgeniy Stepanov
34984610ed7SEvgeniy Stepanov# Zygote wrapper.
350df5ba147SEvgeniy Stepanovif [[ -f "$TMPDIR/app_process64" ]]; then
351df5ba147SEvgeniy Stepanov  # A 64-bit device.
352df5ba147SEvgeniy Stepanov  if [[ ! -f "$TMPDIR/app_process64.real" ]]; then
353df5ba147SEvgeniy Stepanov    # New installation.
354df5ba147SEvgeniy Stepanov    mv "$TMPDIR/app_process32" "$TMPDIR/app_process32.real"
355df5ba147SEvgeniy Stepanov    mv "$TMPDIR/app_process64" "$TMPDIR/app_process64.real"
356df5ba147SEvgeniy Stepanov  fi
35711d3b279SEvgeniy Stepanov  generate_zygote_wrapper "app_process32" "/system/bin/app_process32.real"
35811d3b279SEvgeniy Stepanov  generate_zygote_wrapper "app_process64" "/system/bin/app_process64.real"
359df5ba147SEvgeniy Stepanovelse
360df5ba147SEvgeniy Stepanov  # A 32-bit device.
36111d3b279SEvgeniy Stepanov  generate_zygote_wrapper "app_process.wrap" "/system/bin/app_process32"
362df5ba147SEvgeniy Stepanovfi
36384610ed7SEvgeniy Stepanov
36484610ed7SEvgeniy Stepanov# General command-line tool wrapper (use for anything that's not started as
36584610ed7SEvgeniy Stepanov# zygote).
36684610ed7SEvgeniy Stepanovcat <<EOF >"$TMPDIR/asanwrapper"
36784610ed7SEvgeniy Stepanov#!/system/bin/sh
36811d3b279SEvgeniy StepanovLD_PRELOAD=$ASAN_RT_SYMLINK \\
36984610ed7SEvgeniy Stepanovexec \$@
37084610ed7SEvgeniy Stepanov
37184610ed7SEvgeniy StepanovEOF
37284610ed7SEvgeniy Stepanov
373df5ba147SEvgeniy Stepanovif [[ -n "$ASAN_RT64" ]]; then
374df5ba147SEvgeniy Stepanov  cat <<EOF >"$TMPDIR/asanwrapper64"
375df5ba147SEvgeniy Stepanov#!/system/bin/sh
37611d3b279SEvgeniy StepanovLD_PRELOAD=$ASAN_RT_SYMLINK \\
377df5ba147SEvgeniy Stepanovexec \$@
378df5ba147SEvgeniy Stepanov
379df5ba147SEvgeniy StepanovEOF
380df5ba147SEvgeniy Stepanovfi
381df5ba147SEvgeniy Stepanov
382df5ba147SEvgeniy Stepanovfunction install { # from, to, chmod, chcon
383df5ba147SEvgeniy Stepanov  local _from=$1
384df5ba147SEvgeniy Stepanov  local _to=$2
385df5ba147SEvgeniy Stepanov  local _mode=$3
386df5ba147SEvgeniy Stepanov  local _context=$4
387df5ba147SEvgeniy Stepanov  local _basename="$(basename "$_from")"
388df5ba147SEvgeniy Stepanov  echo "Installing $_to/$_basename $_mode $_context"
389df5ba147SEvgeniy Stepanov  adb_push "$_from" "$_to/$_basename"
390df5ba147SEvgeniy Stepanov  adb_shell chown root.shell "$_to/$_basename"
391df5ba147SEvgeniy Stepanov  if [[ -n "$_mode" ]]; then
392df5ba147SEvgeniy Stepanov    adb_shell chmod "$_mode" "$_to/$_basename"
393df5ba147SEvgeniy Stepanov  fi
394df5ba147SEvgeniy Stepanov  if [[ -n "$_context" ]]; then
395df5ba147SEvgeniy Stepanov    adb_shell chcon "$_context" "$_to/$_basename"
396df5ba147SEvgeniy Stepanov  fi
397df5ba147SEvgeniy Stepanov}
398df5ba147SEvgeniy Stepanov
39984610ed7SEvgeniy Stepanovif ! ( cd "$TMPDIRBASE" && diff -qr old/ new/ ) ; then
400a5d07482SEvgeniy Stepanov    # Make SELinux happy by keeping app_process wrapper and the shell
401a5d07482SEvgeniy Stepanov    # it runs on in zygote domain.
4023f11c0d7SEvgeniy Stepanov    ENFORCING=0
40384d30ba4SEvgeniy Stepanov    if adb_shell getenforce | grep Enforcing >/dev/null; then
4043f11c0d7SEvgeniy Stepanov        # Sometimes shell is not allowed to change file contexts.
4053f11c0d7SEvgeniy Stepanov        # Temporarily switch to permissive.
4063f11c0d7SEvgeniy Stepanov        ENFORCING=1
40784d30ba4SEvgeniy Stepanov        adb_shell setenforce 0
4083f11c0d7SEvgeniy Stepanov    fi
4093f11c0d7SEvgeniy Stepanov
4103f11c0d7SEvgeniy Stepanov    if [[ PRE_L -eq 1 ]]; then
4113f11c0d7SEvgeniy Stepanov        CTX=u:object_r:system_file:s0
4123f11c0d7SEvgeniy Stepanov    else
4133f11c0d7SEvgeniy Stepanov        CTX=u:object_r:zygote_exec:s0
4143f11c0d7SEvgeniy Stepanov    fi
415df5ba147SEvgeniy Stepanov
416df5ba147SEvgeniy Stepanov    echo '>> Pushing files to the device'
417df5ba147SEvgeniy Stepanov
418df5ba147SEvgeniy Stepanov    if [[ -n "$ASAN_RT64" ]]; then
419df5ba147SEvgeniy Stepanov      install "$TMPDIR/$ASAN_RT" /system/lib 644
420df5ba147SEvgeniy Stepanov      install "$TMPDIR/$ASAN_RT64" /system/lib64 644
421df5ba147SEvgeniy Stepanov      install "$TMPDIR/app_process32" /system/bin 755 $CTX
422df5ba147SEvgeniy Stepanov      install "$TMPDIR/app_process32.real" /system/bin 755 $CTX
423df5ba147SEvgeniy Stepanov      install "$TMPDIR/app_process64" /system/bin 755 $CTX
424df5ba147SEvgeniy Stepanov      install "$TMPDIR/app_process64.real" /system/bin 755 $CTX
425df5ba147SEvgeniy Stepanov      install "$TMPDIR/asanwrapper" /system/bin 755
426df5ba147SEvgeniy Stepanov      install "$TMPDIR/asanwrapper64" /system/bin 755
42711d3b279SEvgeniy Stepanov
4280b44f44bSEvgeniy Stepanov      adb_shell rm -f /system/lib/$ASAN_RT_SYMLINK
4290b44f44bSEvgeniy Stepanov      adb_shell ln -s $ASAN_RT /system/lib/$ASAN_RT_SYMLINK
4300b44f44bSEvgeniy Stepanov      adb_shell rm -f /system/lib64/$ASAN_RT_SYMLINK
4310b44f44bSEvgeniy Stepanov      adb_shell ln -s $ASAN_RT64 /system/lib64/$ASAN_RT_SYMLINK
432df5ba147SEvgeniy Stepanov    else
433df5ba147SEvgeniy Stepanov      install "$TMPDIR/$ASAN_RT" /system/lib 644
4342253d1c0SEvgeniy Stepanov      install "$TMPDIR/app_process32" /system/bin 755 $CTX
435df5ba147SEvgeniy Stepanov      install "$TMPDIR/app_process.wrap" /system/bin 755 $CTX
436df5ba147SEvgeniy Stepanov      install "$TMPDIR/asanwrapper" /system/bin 755 $CTX
437df5ba147SEvgeniy Stepanov
4380b44f44bSEvgeniy Stepanov      adb_shell rm -f /system/lib/$ASAN_RT_SYMLINK
4390b44f44bSEvgeniy Stepanov      adb_shell ln -s $ASAN_RT /system/lib/$ASAN_RT_SYMLINK
44011d3b279SEvgeniy Stepanov
441df5ba147SEvgeniy Stepanov      adb_shell rm /system/bin/app_process
442df5ba147SEvgeniy Stepanov      adb_shell ln -s /system/bin/app_process.wrap /system/bin/app_process
443df5ba147SEvgeniy Stepanov    fi
444df5ba147SEvgeniy Stepanov
445df5ba147SEvgeniy Stepanov    adb_shell cp /system/bin/sh /system/bin/sh-from-zygote
446df5ba147SEvgeniy Stepanov    adb_shell chcon $CTX /system/bin/sh-from-zygote
4473f11c0d7SEvgeniy Stepanov
44829c74871SEvgeniy Stepanov    if [[ ANDROID_O -eq 1 ]]; then
44929c74871SEvgeniy Stepanov      # For Android O, the linker namespace is temporarily disabled.
45029c74871SEvgeniy Stepanov      adb_shell mv /system/etc/ld.config.txt /system/etc/ld.config.txt.saved
45129c74871SEvgeniy Stepanov    fi
45229c74871SEvgeniy Stepanov
4533f11c0d7SEvgeniy Stepanov    if [ $ENFORCING == 1 ]; then
45484d30ba4SEvgeniy Stepanov        adb_shell setenforce 1
4553f11c0d7SEvgeniy Stepanov    fi
456a5d07482SEvgeniy Stepanov
45784610ed7SEvgeniy Stepanov    echo '>> Restarting shell (asynchronous)'
45884d30ba4SEvgeniy Stepanov    adb_shell stop
45984d30ba4SEvgeniy Stepanov    adb_shell start
46084610ed7SEvgeniy Stepanov
46184610ed7SEvgeniy Stepanov    echo '>> Please wait until the device restarts'
46284610ed7SEvgeniy Stepanovelse
46384610ed7SEvgeniy Stepanov    echo '>> Device is up to date'
46484610ed7SEvgeniy Stepanovfi
46584610ed7SEvgeniy Stepanov
46684610ed7SEvgeniy Stepanovrm -r "$TMPDIRBASE"
467