[compiler-rt] r229368 - [asan] Support 'su' rooted devices in ASan setup script.
Evgeniy Stepanov
eugeni.stepanov at gmail.com
Mon Feb 16 02:22:19 PST 2015
Author: eugenis
Date: Mon Feb 16 04:22:12 2015
New Revision: 229368
URL: http://llvm.org/viewvc/llvm-project?rev=229368&view=rev
Log:
[asan] Support 'su' rooted devices in ASan setup script.
Android devices may not support 'adb root', but be rooted with 'su'
binary. This patch makes it possible to install ASAN to such
devices. When --use-su flag is specified, most 'adb ...' commangs are
changed to 'adb su -c "..."'.
Some other notes:
* 'readlink' changed to 'ls -l', since not all devices have readlink
in their firmware.
* removing ASan library step moved to very end, because 'su' may not
run properly without this library until shell will be restarted.
Patch by Dmitry <ripp at yandex-team dot ru>.
Modified:
compiler-rt/trunk/lib/asan/scripts/asan_device_setup
Modified: compiler-rt/trunk/lib/asan/scripts/asan_device_setup
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/scripts/asan_device_setup?rev=229368&r1=229367&r2=229368&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/scripts/asan_device_setup (original)
+++ compiler-rt/trunk/lib/asan/scripts/asan_device_setup Mon Feb 16 04:22:12 2015
@@ -18,6 +18,7 @@ revert=no
extra_options=
device=
lib=
+use_su=0
function usage {
echo "usage: $0 [--revert] [--device device-id] [--lib path] [--extra-options options]"
@@ -26,13 +27,70 @@ function usage {
echo " --extra-options: Extra ASAN_OPTIONS."
echo " --device: Install to the given device. Use 'adb devices' to find"
echo " device-id."
+ echo " --use-su: Use 'su -c' prefix for every adb command instead of using"
+ echo " 'adb root' once."
echo
exit 1
}
+function adb_push {
+ if [ $use_su -eq 0 ]; then
+ $ADB push "$1" "$2"
+ else
+ local FILENAME=$(basename $1)
+ $ADB push "$1" "/data/local/tmp/$FILENAME"
+ $ADB shell su -c "rm \\\"$2/$FILENAME\\\"" >&/dev/null
+ $ADB shell su -c "cat \\\"/data/local/tmp/$FILENAME\\\" > \\\"$2/$FILENAME\\\""
+ $ADB shell su -c "rm \\\"/data/local/tmp/$FILENAME\\\""
+ fi
+}
+
+function adb_remount {
+ if [ $use_su -eq 0 ]; then
+ $ADB remount
+ else
+ local STORAGE=`$ADB shell mount | grep /system | cut -d ' ' -f1`
+ if [ "$STORAGE" != "" ]; then
+ echo Remounting $STORAGE at /system
+ $ADB shell su -c "mount -o remount,rw $STORAGE /system"
+ else
+ echo Failed to get storage device name for "/system" mount point
+ fi
+ fi
+}
+
+function adb_shell {
+ if [ $use_su -eq 0 ]; then
+ $ADB shell $@
+ else
+ $ADB shell su -c "$*"
+ fi
+}
+
+function adb_root {
+ if [ $use_su -eq 0 ]; then
+ $ADB root
+ fi
+}
+
+function adb_wait_for_device {
+ $ADB wait-for-device
+}
+
+function adb_pull {
+ if [ $use_su -eq 0 ]; then
+ $ADB pull "$1" "$2"
+ else
+ local FILENAME=$(basename $1)
+ $ADB shell rm "/data/local/tmp/$FILENAME" >&/dev/null
+ $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\\\"" &&
+ $ADB pull "/data/local/tmp/$FILENAME" "$2" >&/dev/null && $ADB shell "rm \"/data/local/tmp/$FILENAME\""
+ fi
+}
+
function get_device_arch { # OUTVAR
local _outvar=$1
- local _ABI=$($ADB shell getprop ro.product.cpu.abi)
+ local _ABI=$(adb_shell getprop ro.product.cpu.abi)
local _ARCH=
if [[ $_ABI == x86* ]]; then
_ARCH=i686
@@ -74,6 +132,9 @@ while [[ $# > 0 ]]; do
fi
device="$1"
;;
+ --use-su)
+ use_su=1
+ ;;
*)
usage
;;
@@ -86,12 +147,25 @@ if [[ x$device != x ]]; then
ADB="$ADB -s $device"
fi
+if [ $use_su -eq 1 ]; then
+ # Test if 'su' is present on the device
+ SU_TEST_OUT=`$ADB shell su -c "echo foo" 2>&1 | sed 's/\r$//'`
+ if [ $? != 0 -o "$SU_TEST_OUT" != "foo" ]; then
+ echo "ERROR: Cannot use 'su -c':"
+ echo "$ adb shell su -c \"echo foo\""
+ echo $SU_TEST_OUT
+ echo "Check that 'su' binary is correctly installed on the device or omit"
+ echo " --use-su flag"
+ exit 1
+ fi
+fi
+
echo '>> Remounting /system rw'
-$ADB wait-for-device
-$ADB root
-$ADB wait-for-device
-$ADB remount
-$ADB wait-for-device
+adb_wait_for_device
+adb_root
+adb_wait_for_device
+adb_remount
+adb_wait_for_device
get_device_arch ARCH
echo "Target architecture: $ARCH"
@@ -100,22 +174,24 @@ ASAN_RT="libclang_rt.asan-$ARCH-android.
if [[ x$revert == xyes ]]; then
echo '>> Uninstalling ASan'
- if ! $ADB shell readlink /system/bin/app_process | grep 'app_process' >&/dev/null; then
+ if ! adb_shell ls -l /system/bin/app_process | grep -o '\->.*app_process' >&/dev/null; then
echo '>> Pre-L device detected.'
- $ADB shell mv /system/bin/app_process.real /system/bin/app_process
- $ADB shell rm /system/bin/asanwrapper
- $ADB shell rm /system/lib/$ASAN_RT
+ adb_shell mv /system/bin/app_process.real /system/bin/app_process
+ adb_shell rm /system/bin/asanwrapper
else
- $ADB shell rm /system/bin/app_process.wrap
- $ADB shell rm /system/bin/asanwrapper
- $ADB shell rm /system/lib/$ASAN_RT
- $ADB shell rm /system/bin/app_process
- $ADB shell ln -s /system/bin/app_process32 /system/bin/app_process
+ adb_shell rm /system/bin/app_process.wrap
+ adb_shell rm /system/bin/asanwrapper
+ adb_shell rm /system/bin/app_process
+ adb_shell ln -s /system/bin/app_process32 /system/bin/app_process
fi
echo '>> Restarting shell'
- $ADB shell stop
- $ADB shell start
+ adb_shell stop
+ adb_shell start
+
+ # Remove the library on the last step to give a chance to the 'su' binary to
+ # be executed without problem.
+ adb_shell rm /system/lib/$ASAN_RT
echo '>> Done'
exit 0
@@ -146,28 +222,28 @@ TMPDIROLD="$TMPDIRBASE/old"
TMPDIR="$TMPDIRBASE/new"
mkdir "$TMPDIROLD"
-RELEASE=$($ADB shell getprop ro.build.version.release)
+RELEASE=$(adb_shell getprop ro.build.version.release)
PRE_L=0
if echo "$RELEASE" | grep '^4\.' >&/dev/null; then
PRE_L=1
fi
-if ! $ADB shell readlink /system/bin/app_process | grep 'app_process' >&/dev/null; then
+if ! adb_shell ls -l /system/bin/app_process | grep -o '\->.*app_process' >&/dev/null; then
- if $ADB pull /system/bin/app_process.real /dev/null >&/dev/null; then
+ if adb_pull /system/bin/app_process.real /dev/null >&/dev/null; then
echo '>> Old-style ASan installation detected. Reverting.'
- $ADB shell mv /system/bin/app_process.real /system/bin/app_process
+ adb_shell mv /system/bin/app_process.real /system/bin/app_process
fi
echo '>> Pre-L device detected. Setting up app_process symlink.'
- $ADB shell mv /system/bin/app_process /system/bin/app_process32
- $ADB shell ln -s /system/bin/app_process32 /system/bin/app_process
+ adb_shell mv /system/bin/app_process /system/bin/app_process32
+ adb_shell ln -s /system/bin/app_process32 /system/bin/app_process
fi
echo '>> Copying files from the device'
-$ADB pull /system/bin/app_process.wrap "$TMPDIROLD" || true
-$ADB pull /system/bin/asanwrapper "$TMPDIROLD" || true
-$ADB pull /system/lib/"$ASAN_RT" "$TMPDIROLD" || true
+adb_pull /system/bin/app_process.wrap "$TMPDIROLD" || true
+adb_pull /system/bin/asanwrapper "$TMPDIROLD" || true
+adb_pull /system/lib/"$ASAN_RT" "$TMPDIROLD" || true
cp -r "$TMPDIROLD" "$TMPDIR"
if [[ -f "$TMPDIR/app_process.wrap" ]]; then
@@ -213,52 +289,52 @@ EOF
if ! ( cd "$TMPDIRBASE" && diff -qr old/ new/ ) ; then
echo '>> Pushing files to the device'
- $ADB push "$TMPDIR/$ASAN_RT" /system/lib/
- $ADB push "$TMPDIR/app_process.wrap" /system/bin/app_process.wrap
- $ADB push "$TMPDIR/asanwrapper" /system/bin/asanwrapper
+ adb_push "$TMPDIR/$ASAN_RT" /system/lib/
+ adb_push "$TMPDIR/app_process.wrap" /system/bin
+ adb_push "$TMPDIR/asanwrapper" /system/bin
- $ADB shell rm /system/bin/app_process
- $ADB shell ln -s /system/bin/app_process.wrap /system/bin/app_process
+ adb_shell rm /system/bin/app_process
+ adb_shell ln -s /system/bin/app_process.wrap /system/bin/app_process
- $ADB shell chown root.shell \
+ adb_shell chown root.shell \
/system/lib/"$ASAN_RT" \
/system/bin/app_process.wrap \
/system/bin/asanwrapper
- $ADB shell chmod 644 \
+ adb_shell chmod 644 \
/system/lib/"$ASAN_RT"
- $ADB shell chmod 755 \
+ adb_shell chmod 755 \
/system/bin/app_process.wrap \
/system/bin/asanwrapper
# Make SELinux happy by keeping app_process wrapper and the shell
# it runs on in zygote domain.
ENFORCING=0
- if $ADB shell getenforce | grep Enforcing >/dev/null; then
+ if adb_shell getenforce | grep Enforcing >/dev/null; then
# Sometimes shell is not allowed to change file contexts.
# Temporarily switch to permissive.
ENFORCING=1
- $ADB shell setenforce 0
+ adb_shell setenforce 0
fi
- $ADB shell cp /system/bin/sh /system/bin/sh-from-zygote
+ adb_shell cp /system/bin/sh /system/bin/sh-from-zygote
if [[ PRE_L -eq 1 ]]; then
CTX=u:object_r:system_file:s0
else
CTX=u:object_r:zygote_exec:s0
fi
- $ADB shell chcon $CTX \
+ adb_shell chcon $CTX \
/system/bin/sh-from-zygote \
/system/bin/app_process.wrap \
/system/bin/app_process32
if [ $ENFORCING == 1 ]; then
- $ADB shell setenforce 1
+ adb_shell setenforce 1
fi
echo '>> Restarting shell (asynchronous)'
- $ADB shell stop
- $ADB shell start
+ adb_shell stop
+ adb_shell start
echo '>> Please wait until the device restarts'
else
More information about the llvm-commits
mailing list