2 #===- lib/asan/scripts/asan_device_setup -----------------------------------===#
4 # The LLVM Compiler Infrastructure
6 # This file is distributed under the University of Illinois Open Source
7 # License. See LICENSE.TXT for details.
9 # Prepare Android device to run ASan applications.
11 #===------------------------------------------------------------------------===#
15 HERE
="$(cd "$
(dirname "$0")" && pwd)"
24 echo "usage: $0 [--revert] [--device device-id] [--lib path] [--extra-options options]"
25 echo " --revert: Uninstall ASan from the device."
26 echo " --lib: Path to ASan runtime library."
27 echo " --extra-options: Extra ASAN_OPTIONS."
28 echo " --device: Install to the given device. Use 'adb devices' to find"
30 echo " --use-su: Use 'su -c' prefix for every adb command instead of using"
31 echo " 'adb root' once."
37 if [ $use_su -eq 0 ]; then
40 local FILENAME
=$
(basename $1)
41 $ADB push
"$1" "/data/local/tmp/$FILENAME"
42 $ADB shell su
-c "rm \\\"$2/$FILENAME\\\"" >&/dev
/null
43 $ADB shell su
-c "cat \\\"/data/local/tmp/$FILENAME\\\" > \\\"$2/$FILENAME\\\""
44 $ADB shell su
-c "rm \\\"/data/local/tmp/$FILENAME\\\""
48 function adb_remount
{
49 if [ $use_su -eq 0 ]; then
52 local STORAGE
=`$ADB shell mount | grep /system | cut -d ' ' -f1`
53 if [ "$STORAGE" != "" ]; then
54 echo Remounting
$STORAGE at /system
55 $ADB shell su
-c "mount -o remount,rw $STORAGE /system"
57 echo Failed to get storage device name
for "/system" mount point
63 if [ $use_su -eq 0 ]; then
71 if [ $use_su -eq 0 ]; then
76 function adb_wait_for_device
{
81 if [ $use_su -eq 0 ]; then
84 local FILENAME
=$
(basename $1)
85 $ADB shell
rm "/data/local/tmp/$FILENAME" >&/dev
/null
86 $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\\\"" &&
87 $ADB pull
"/data/local/tmp/$FILENAME" "$2" >&/dev
/null
&& $ADB shell
"rm \"/data/local/tmp/$FILENAME\""
91 function get_device_arch
{ # OUT OUT64
94 local _ABI
=$
(adb_shell getprop ro.product.cpu.abi
)
97 if [[ $_ABI == x86
* ]]; then
99 elif [[ $_ABI == armeabi
* ]]; then
101 elif [[ $_ABI == arm64-v8a
* ]]; then
105 echo "Unrecognized device ABI: $_ABI"
108 eval $_outvar=\
$_ARCH
109 eval $_outvar64=\
$_ARCH64
112 while [[ $# > 0 ]]; do
119 if [[ $# == 0 ]]; then
120 echo "--extra-options requires an argument."
127 if [[ $# == 0 ]]; then
128 echo "--lib requires an argument."
135 if [[ $# == 0 ]]; then
136 echo "--device requires an argument."
152 if [[ x
$device != x
]]; then
153 ADB
="$ADB -s $device"
156 if [ $use_su -eq 1 ]; then
157 # Test if 'su' is present on the device
158 SU_TEST_OUT
=`$ADB shell su -c "echo foo" 2>&1 | sed 's/\r$//'`
159 if [ $?
!= 0 -o "$SU_TEST_OUT" != "foo" ]; then
160 echo "ERROR: Cannot use 'su -c':"
161 echo "$ adb shell su -c \"echo foo\""
163 echo "Check that 'su' binary is correctly installed on the device or omit"
164 echo " --use-su flag"
169 echo '>> Remounting /system rw'
176 get_device_arch ARCH ARCH64
177 echo "Target architecture: $ARCH"
178 ASAN_RT
="libclang_rt.asan-$ARCH-android.so"
179 if [[ -n $ARCH64 ]]; then
180 echo "Target architecture: $ARCH64"
181 ASAN_RT64
="libclang_rt.asan-$ARCH64-android.so"
184 if [[ x
$revert == xyes
]]; then
185 echo '>> Uninstalling ASan'
187 if ! adb_shell
ls -l /system
/bin
/app_process |
grep -o '\->.*app_process' >&/dev
/null
; then
188 echo '>> Pre-L device detected.'
189 adb_shell
mv /system
/bin
/app_process.real
/system
/bin
/app_process
190 adb_shell
rm /system
/bin
/asanwrapper
191 elif ! adb_shell
ls -l /system
/bin
/app_process64.real |
grep -o 'No such file or directory' >&/dev
/null
; then
192 # 64-bit installation.
193 adb_shell
mv /system
/bin
/app_process32.real
/system
/bin
/app_process32
194 adb_shell
mv /system
/bin
/app_process64.real
/system
/bin
/app_process64
195 adb_shell
rm /system
/bin
/asanwrapper
196 adb_shell
rm /system
/bin
/asanwrapper64
198 # 32-bit installation.
199 adb_shell
rm /system
/bin
/app_process.wrap
200 adb_shell
rm /system
/bin
/asanwrapper
201 adb_shell
rm /system
/bin
/app_process
202 adb_shell
ln -s /system
/bin
/app_process32
/system
/bin
/app_process
205 echo '>> Restarting shell'
209 # Remove the library on the last step to give a chance to the 'su' binary to
210 # be executed without problem.
211 adb_shell
rm /system
/lib
/$ASAN_RT
217 if [[ -d "$lib" ]]; then
219 elif [[ -f "$lib" && "$lib" == *"$ASAN_RT" ]]; then
220 ASAN_RT_PATH
=$
(dirname "$lib")
221 elif [[ -f "$HERE/$ASAN_RT" ]]; then
223 elif [[ $
(basename "$HERE") == "bin" ]]; then
224 # We could be in the toolchain's base directory.
225 # Consider ../lib, ../lib/asan, ../lib/linux,
226 # ../lib/clang/$VERSION/lib/linux, and ../lib64/clang/$VERSION/lib/linux.
227 P
=$
(ls "$HERE"/..
/lib
/"$ASAN_RT" \
228 "$HERE"/..
/lib
/asan
/"$ASAN_RT" \
229 "$HERE"/..
/lib
/linux
/"$ASAN_RT" \
230 "$HERE"/..
/lib
/clang
/*/lib
/linux
/"$ASAN_RT" \
231 "$HERE"/..
/lib64
/clang
/*/lib
/linux
/"$ASAN_RT" 2>/dev
/null |
sort |
tail -1)
232 if [[ -n "$P" ]]; then
233 ASAN_RT_PATH
="$(dirname "$P")"
237 if [[ -z "$ASAN_RT_PATH" ||
! -f "$ASAN_RT_PATH/$ASAN_RT" ]]; then
238 echo ">> ASan runtime library not found"
242 if [[ -n "$ASAN_RT64" ]]; then
243 if [[ -z "$ASAN_RT_PATH" ||
! -f "$ASAN_RT_PATH/$ASAN_RT64" ]]; then
244 echo ">> ASan runtime library not found"
249 TMPDIRBASE
=$
(mktemp
-d)
250 TMPDIROLD
="$TMPDIRBASE/old"
251 TMPDIR
="$TMPDIRBASE/new"
254 RELEASE
=$
(adb_shell getprop ro.build.version.release
)
256 if echo "$RELEASE" |
grep '^4\.' >&/dev
/null
; then
260 if ! adb_shell
ls -l /system
/bin
/app_process |
grep -o '\->.*app_process' >&/dev
/null
; then
262 if adb_pull
/system
/bin
/app_process.real
/dev
/null
>&/dev
/null
; then
263 echo '>> Old-style ASan installation detected. Reverting.'
264 adb_shell
mv /system
/bin
/app_process.real
/system
/bin
/app_process
267 echo '>> Pre-L device detected. Setting up app_process symlink.'
268 adb_shell
mv /system
/bin
/app_process
/system
/bin
/app_process32
269 adb_shell
ln -s /system
/bin
/app_process32
/system
/bin
/app_process
272 echo '>> Copying files from the device'
273 if [[ -n "$ASAN_RT64" ]]; then
274 adb_pull
/system
/lib
/"$ASAN_RT" "$TMPDIROLD" || true
275 adb_pull
/system
/lib64
/"$ASAN_RT64" "$TMPDIROLD" || true
276 adb_pull
/system
/bin
/app_process32
"$TMPDIROLD" || true
277 adb_pull
/system
/bin
/app_process32.real
"$TMPDIROLD" || true
278 adb_pull
/system
/bin
/app_process64
"$TMPDIROLD" || true
279 adb_pull
/system
/bin
/app_process64.real
"$TMPDIROLD" || true
280 adb_pull
/system
/bin
/asanwrapper
"$TMPDIROLD" || true
281 adb_pull
/system
/bin
/asanwrapper64
"$TMPDIROLD" || true
283 adb_pull
/system
/lib
/"$ASAN_RT" "$TMPDIROLD" || true
284 adb_pull
/system
/bin
/app_process32
"$TMPDIROLD" || true
285 adb_pull
/system
/bin
/app_process.wrap
"$TMPDIROLD" || true
286 adb_pull
/system
/bin
/asanwrapper
"$TMPDIROLD" || true
288 cp -r "$TMPDIROLD" "$TMPDIR"
290 if [[ -f "$TMPDIR/app_process.wrap" ||
-f "$TMPDIR/app_process64.real" ]]; then
291 echo ">> Previous installation detected"
293 echo ">> New installation"
296 echo '>> Generating wrappers'
298 cp "$ASAN_RT_PATH/$ASAN_RT" "$TMPDIR/"
299 if [[ -n "$ASAN_RT64" ]]; then
300 cp "$ASAN_RT_PATH/$ASAN_RT64" "$TMPDIR/"
303 # FIXME: alloc_dealloc_mismatch=0 prevents a failure in libdvm startup,
304 # which may or may not be a real bug (probably not).
305 ASAN_OPTIONS
=start_deactivated
=1,alloc_dealloc_mismatch
=0,malloc_context_size
=0
307 function generate_zygote_wrapper
{ # from, to, asan_rt
311 if [[ PRE_L
-eq 0 ]]; then
312 # LD_PRELOAD parsing is broken in N if it starts with ":". Luckily, it is
313 # unset in the system environment since L.
314 local _ld_preload
=$_asan_rt
316 local _ld_preload
=\
$LD_PRELOAD:$_asan_rt
318 cat <<EOF >"$TMPDIR/$_from"
319 #!/system/bin/sh-from-zygote
320 ASAN_OPTIONS=$ASAN_OPTIONS \\
321 ASAN_ACTIVATION_OPTIONS=include_if_exists=/data/local/tmp/asan.options.%b \\
322 LD_PRELOAD=$_ld_preload \\
328 # On Android-L not allowing user segv handler breaks some applications.
329 if [[ PRE_L
-eq 0 ]]; then
330 ASAN_OPTIONS
="$ASAN_OPTIONS,allow_user_segv_handler=1"
333 if [[ x
$extra_options != x
]] ; then
334 ASAN_OPTIONS
="$ASAN_OPTIONS,$extra_options"
338 if [[ -f "$TMPDIR/app_process64" ]]; then
340 if [[ ! -f "$TMPDIR/app_process64.real" ]]; then
342 mv "$TMPDIR/app_process32" "$TMPDIR/app_process32.real"
343 mv "$TMPDIR/app_process64" "$TMPDIR/app_process64.real"
345 generate_zygote_wrapper
"app_process32" "/system/bin/app_process32.real" "$ASAN_RT"
346 generate_zygote_wrapper
"app_process64" "/system/bin/app_process64.real" "$ASAN_RT64"
349 generate_zygote_wrapper
"app_process.wrap" "/system/bin/app_process32" "$ASAN_RT"
352 # General command-line tool wrapper (use for anything that's not started as
354 cat <<EOF >"$TMPDIR/asanwrapper"
356 LD_PRELOAD=$ASAN_RT \\
361 if [[ -n "$ASAN_RT64" ]]; then
362 cat <<EOF >"$TMPDIR/asanwrapper64"
364 LD_PRELOAD=$ASAN_RT64 \\
370 function install { # from, to, chmod, chcon
375 local _basename
="$(basename "$_from")"
376 echo "Installing $_to/$_basename $_mode $_context"
377 adb_push
"$_from" "$_to/$_basename"
378 adb_shell chown root.shell
"$_to/$_basename"
379 if [[ -n "$_mode" ]]; then
380 adb_shell
chmod "$_mode" "$_to/$_basename"
382 if [[ -n "$_context" ]]; then
383 adb_shell chcon
"$_context" "$_to/$_basename"
387 if ! ( cd "$TMPDIRBASE" && diff -qr old
/ new
/ ) ; then
388 # Make SELinux happy by keeping app_process wrapper and the shell
389 # it runs on in zygote domain.
391 if adb_shell getenforce |
grep Enforcing
>/dev
/null
; then
392 # Sometimes shell is not allowed to change file contexts.
393 # Temporarily switch to permissive.
395 adb_shell setenforce
0
398 if [[ PRE_L
-eq 1 ]]; then
399 CTX
=u
:object_r
:system_file
:s0
401 CTX
=u
:object_r
:zygote_exec
:s0
404 echo '>> Pushing files to the device'
406 if [[ -n "$ASAN_RT64" ]]; then
407 install "$TMPDIR/$ASAN_RT" /system
/lib
644
408 install "$TMPDIR/$ASAN_RT64" /system
/lib64
644
409 install "$TMPDIR/app_process32" /system
/bin
755 $CTX
410 install "$TMPDIR/app_process32.real" /system
/bin
755 $CTX
411 install "$TMPDIR/app_process64" /system
/bin
755 $CTX
412 install "$TMPDIR/app_process64.real" /system
/bin
755 $CTX
413 install "$TMPDIR/asanwrapper" /system
/bin
755
414 install "$TMPDIR/asanwrapper64" /system
/bin
755
416 install "$TMPDIR/$ASAN_RT" /system
/lib
644
417 install "$TMPDIR/app_process32" /system
/bin
755 $CTX
418 install "$TMPDIR/app_process.wrap" /system
/bin
755 $CTX
419 install "$TMPDIR/asanwrapper" /system
/bin
755 $CTX
421 adb_shell
rm /system
/bin
/app_process
422 adb_shell
ln -s /system
/bin
/app_process.wrap
/system
/bin
/app_process
425 adb_shell
cp /system
/bin
/sh
/system
/bin
/sh-from-zygote
426 adb_shell chcon
$CTX /system
/bin
/sh-from-zygote
428 if [ $ENFORCING == 1 ]; then
429 adb_shell setenforce
1
432 echo '>> Restarting shell (asynchronous)'
436 echo '>> Please wait until the device restarts'
438 echo '>> Device is up to date'