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