1. ASan和HWAsan比较 ASan HWASan 全称 Address Sanitizer Hardware-assisted AddressSanitizer 版本 可以在32位和64位的x86、x86-64上。 从
ASan | HWASan | |
全称 | Address Sanitizer | Hardware-assisted AddressSanitizer |
版本 | 可以在32位和64位的x86、x86-64上。 从api 27(Android O MR 1)开始,Android NDK 可支持ASAN。 在Android 11 之后的AOSP master中,弃用了arm64 上的平台开发ASan,改为使用HWASan。 | 只在Android 10 及以上版本有效,且只使用于AArch64硬件平台。 |
检测bugs | Stack and heap buffer overflow/underflow Heap use after free Stack use outside scope Double free/wild free | Stack and heap buffer overflow/underflow Heap use after free Stack use outside scope Double free/wild free stack use after return |
要求 | CPU 开销(~ 2倍) 代码大小开销(50% ~ 2倍) 内存开销(~ 2倍) | CPU 开销(~ 2倍) 代码大小开销(40% ~ 50%) 内存开销(10% ~ 35%) |
原理 | 使用shadow memory(内存的一个区域)内存状态进行标记,如free掉的内存在shadow中标记为0xfd,已经申请的内存,前后存在安全区标记为0xfa | AArch64是64位的架构,一个64bit的指针值,其中真正用于寻址的只有低48位。 AArch64拥有地址标记(Address tagging, or top-byte-ignore)的特性,它表示允许软件使用64bit指针值的高8位开发特定功能。HWASAN用这8bit来存储一块内存区域的标签(tag)。 |
缺点 | 1)ASAN的运行是需要消耗memory和CPU资源的,此外它也会增加代码大小。它的性能相比于之前的工具确实有了质的提升,但仍然无法适用于某些压力测试场景,尤其是需要全局打开的时候。这一点在Android上尤为明显,每当我们想要全局打开ASAN调试某些奇葩问题时,系统总会因为负载过重而跑不起来; 2)对于 free 的内存标记存在隔离时间,即 free 的区域一段时间后重新分配其他所有者,此时原持有者访问不会报错; 3)对应flow的安全区总归有大小,如果踩踏过了安全区,同样不会报错; | 1)可移植性差,只用于64位平台; 2)需要对linux Kernel做一些改动以支持工具 3)对于所有错误的检测将有一定概率false negative(漏掉一些真实的错误),概率为1/256。原因是tag的生成只能从256(2的8次方)个数中选一个,因此不同地址的tag将有可能相同 |
优点 | 比较ASan: 1)不再需要安全区来检测buffer overflow,既极大地降低了工具对于内存的消耗,也不会出现ASAN中某些overflow检测不到的情况; 2)不再需要隔离区来检测UseAfterFree,因此不会出现ASAN中某些UseAfterFree检测不到的情况 |
m -j16SANITIZE_TARGET=address m -j16
注意,这里需要两次编译。第一次是为了在 /system/lib 中编译常规库,第二次编译是为了在 /system/lib/asan 中进行 ASan 插桩。
需要刷新system、vendor、system分区,因为上述第 2 步编译ASAN库在/data/asan目录下。
Android.mkLOCAL_SANITIZE := address Android.bpsanitize: { address: true }
LOCAL_SANITIZE:=addressLOCAL_MODULE_RELATIVE_PATH := asan
这样一来,系统会将库放到 /system/lib/asan 中而非 /system/lib 中。但是需要指定库的路径方便链接:
LD_LIBRARY_PATH=/system/lib/asan或setenv LD_LIBRARY_PATH /system/lib/asan
通过 /proc/PID/maps 验证使用的库是否来自 /system/lib/asan(如果此库存在),如果不是,可能需要停用 selinux:
adb rootadb shell setenforce 0# restart the process with adb shell kill $PID# if it is a system service, or may be adb shell stop; adb shell start.
有些目标无法使用ASan 构建:
在 SANITIZE_TARGET build 中,系统会跳过此类可执行文件,且会将第一个make 调用中构建的版本留在 /system/bin 中。
export SANITIZE_TARGET=hwaddreSSM -j16
与ASan 不同,HWASan 无需构建两次,只需增量构建,没有特殊的刷写指令,不需要擦除,支持静态可执行文件,并且可以跳过除 libc 之外的任何库的排错。
通过环境变量 SANITIZE_TARGET 指定排错(sanitizer)。
在编译脚本中增加如下参数即可
Android.mkLOCAL_SANITIZE:= hwaddress Android.bpsanitize: { hwaddress: true }
如果需要在整体构建中,去除某模块HWASAN的编译
Android.mkLOCAL_NOSANITIZE := hwaddress Android.bpsanitize: { hwaddress: false}
由于版本默认库或者bin是stripped过的,因此无法解析,如
==4415==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x003a861bb057 at pc 0x00775f3c664c bp 0x007fd0f434b0 sp 0x007fd0f42c90READ of size 8 at 0x003a861bb057 thread T0 #0 0x775f3c6648 (/system/lib64/libclang_rt.asan-aarch64-android.so+0x72648) #1 0x775f3c6ff8 (/system/lib64/libclang_rt.asan-aarch64-android.so+0x72ff8) #2 0x59861bf0a8 (/vendor/bin/qrtr-lookup+0x20a8) #3 0x775f72488c (/apex/com.android.runtime/lib64/bionic/libc.so+0x4988c) 0x003a861bb057 is located 0 bytes to the right of 7-byte region [0x003a861bb050,0x003a861bb057)allocated by thread T0 here: #0 0x775f3f6088 (/system/lib64/libclang_rt.asan-aarch64-android.so+0xa2088) #1 0x59861bf094 (/vendor/bin/qrtr-lookup+0x2094) #2 0x775f72488c (/apex/com.android.runtime/lib64/bionic/libc.so+0x4988c) #3 0x59861bf044 (/vendor/bin/qrtr-lookup+0x2044) #4 0x7760b9fbb4 (/vendor/bin/qrtr-lookup+0x4cbb4) SUMMARY: AddressSanitizer: heap-buffer-overflow (/system/lib64/libclang_rt.asan-aarch64-android.so+0x72648)Shadow bytes around the buggy address: 0x001750c375b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x001750c375c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x001750c375d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x001750c375e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x001750c375f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00=>0x001750c37600: fa fa 00 fa fa fa 00 fa fa fa[07]fa fa fa fa fa 0x001750c37610: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x001750c37620: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x001750c37630: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x001750c37640: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x001750c37650: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa faShadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb Shadow gap: cc==4415==ABORTING
上述工作完成后,当ASAN / HWASan 检查到错误后,相关结果会自动解析到loGCat 或screen 上,包括具体的函数,行号等等
====================================================================6646==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x003c452d8057 at pc 0x00749d4d364c bp 0x007fd09ac530 sp 0x007fd09abd10READ of size 8 at 0x003c452d8057 thread T0 #0 0x749d4d3648 in printf_common(void*, char const*, std::__va_list) /out/llvm-project/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors_format.inc:547:9 #1 0x749d4d3ff8 in __interceptor_vprintf /out/llvm-project/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:1645:1 #2 0x749d4d3ff8 in printf /out/llvm-project/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:1703:1 #3 0x5b452dc1a8 in main vendor/qcom/proprietary/qmi-framework/qrtr/src/lookup.c:143:5 #4 0x749d3a888c in __libc_init (/apex/com.android.runtime/lib64/bionic/libc.so+0x4988c) 0x003c452d8057 is located 0 bytes to the right of 7-byte region [0x003c452d8050,0x003c452d8057)allocated by thread T0 here: #0 0x749d503088 in malloc /out/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:145:3 #1 0x5b452dc194 in main vendor/qcom/proprietary/qmi-framework/qrtr/src/lookup.c:142:21 #2 0x749d3a888c in __libc_init (/apex/com.android.runtime/lib64/bionic/libc.so+0x4988c) #3 0x5b452dc044 in _start_main bionic/libc/arch-common/bionic/crtbegin.c:45:3 #4 0x749eb2dbb4 (/vendor/bin/qrtr-lookup+0x4cbb4) SUMMARY: AddressSanitizer: heap-buffer-overflow /out/llvm-project/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors_format.inc:547:9 in printf_common(void*, char const*, std::__va_list)Shadow bytes around the buggy address: 0x001788a5afb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x001788a5afc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x001788a5afd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x001788a5afe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x001788a5aff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00=>0x001788a5b000: fa fa 00 fa fa fa 00 fa fa fa[07]fa fa fa fa fa 0x001788a5b010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x001788a5b020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x001788a5b030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x001788a5b040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x001788a5b050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa faShadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb Shadow gap: cc==6646==ABORTINGAborted
Android.mkLOCAL_STRIP_MODULE :=falseAndroid.bpstrip :{keep_symbols: true,},
可得到如下信息,得到具体的函数
==10804==ERROR: HWAddressSanitizer: invalid-free on address 0x0038f7647040 at pc 0x0072ed942bb8tags: 1a/96 (ptr/mem) #0 0x72ed942bb4 in __sanitizer_free /out/llvm-project/compiler-rt/lib/hwasan/hwasan_interceptors.cpp:108:3 #1 0x57f764b0b8 in main (/vendor/bin/qrtr-lookup+0x20b8) #2 0x72ed831174 in __libc_init (/apex/com.android.runtime/lib64/bionic/libc.so+0x4e174) #3 0x57f764b044 in _start_main (/vendor/bin/qrtr-lookup+0x2044) #4 0x72eefd3bb4 (/vendor/bin/qrtr-lookup+0x4cbb4) [0x0038f7647040,0x0038f7647060) is a small unallocated heap chunk; size: 32 offset: 00x0038f7647040 is located 0 bytes inside of 7-byte region [0x0038f7647040,0x0038f7647047)freed by thread T0 here: #0 0x72ed942bb4 in __sanitizer_free /out/llvm-project/compiler-rt/lib/hwasan/hwasan_interceptors.cpp:108:3 #1 0x57f764b0b0 in main (/vendor/bin/qrtr-lookup+0x20b0) #2 0x72ed831174 in __libc_init (/apex/com.android.runtime/lib64/bionic/libc.so+0x4e174) #3 0x57f764b044 in _start_main (/vendor/bin/qrtr-lookup+0x2044) #4 0x72eefd3bb4 (/vendor/bin/qrtr-lookup+0x4cbb4) previously allocated here: #0 0x72ed943084 in __sanitizer_malloc /out/llvm-project/compiler-rt/lib/hwasan/hwasan_interceptors.cpp:169:3 #1 0x72ed826bdc in malloc (/apex/com.android.runtime/lib64/bionic/libc.so+0x43bdc) #2 0x57f764b094 in main (/vendor/bin/qrtr-lookup+0x2094) #3 0x72ed831174 in __libc_init (/apex/com.android.runtime/lib64/bionic/libc.so+0x4e174) #4 0x57f764b044 in _start_main (/vendor/bin/qrtr-lookup+0x2044) #5 0x72eefd3bb4 (/vendor/bin/qrtr-lookup+0x4cbb4) hwasan_dev_note_heap_rb_distance: 1 1023Thread: T0 0x006900002000 stack: [0x007fd2fc0000,0x007fd37c0000) sz: 8388608 tls: [0x000000000000,0x000000000000)Memory tags around the buggy address (one tag corresponds to 16 bytes): 0x006d8f764680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006d8f764690: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006d8f7646a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006d8f7646b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006d8f7646c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006d8f7646d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006d8f7646e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006d8f7646f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00=>0x006d8f764700: 08 00 08 00 [96] 00 00 00 00 00 00 00 00 00 00 00 0x006d8f764710: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006d8f764720: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006d8f764730: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006d8f764740: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006d8f764750: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006d8f764760: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006d8f764770: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006d8f764780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00Tags for short granules around the buggy address (one tag corresponds to 16 bytes): 0x006d8f7646f0: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..=>0x006d8f764700: e2 .. 7a .. [..] .. .. .. .. .. .. .. .. .. .. .. 0x006d8f764710: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..See https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html#short-granules for a description of short granule tagsSUMMARY: HWAddressSanitizer: invalid-free /out/llvm-project/compiler-rt/lib/hwasan/hwasan_interceptors.cpp:108:3 in __sanitizer_free
将dump信息copy进入文件dumpinfo,按照如下格式(===开头)
===================================================================24786==ERROR: AddressSanitizer: SEGV on unknown address 0x180001a46bc1c34 (pc 0x00761175f308 bp 0x007fc5f519b0 sp 0x007fc5f51970 T0)==24786==The signal is caused by a READ memory access. #0 0x761175f308 (/system/system_ext/lib64/libimsmedia_jni.so+0x3308) #1 0x761175f1b8 in JNI_OnLoad (/system/system_ext/lib64/libimsmedia_jni.so+0x31b8) #2 0x7681c104d8 in art::JavaVMExt::LoadNativeLibrary(_JNIEnv*, std::__1::basic_string, std::__1::allocator > const&, _jobject*, _jclass*, std::__1::basic_string, std::__1::allocator >*) (/apex/com.android.art/lib64/libart.so+0x5be4d8) #3 0x7678bf2128 in JVM_NativeLoad (/apex/com.android.art/lib64/libopenjdkjvm.so+0x8128) #4 0x6fba7a24 (/apex/com.android.art/javalib/arm64/boot.oat+0x80a24)
然后执行(asan_symbolize路径,android\external\compiler-rt\lib\asan\scripts)
asan_symbolize -s "$OUT/symbols"/ < ./external/compiler-rt/lib/asan/scripts/dumpinfo
#0 0x7332a21308 in _Z18load_ims_media_libPKc vendor/qcom/proprietary/commonsys/telephony-apps/ims/jni/media/ims_media_jni.cpp:477:56 #1 0x7332a211b8 in _Z18load_ims_media_libPKc vendor/qcom/proprietary/commonsys/telephony-apps/ims/jni/media/ims_media_jni.cpp:0:0 #2 0x73a24dc168 in _ZN3art9JavaVMExt17LoadNativeLibraryEP7_JNIEnvRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEP8_jobjectP7_jclassPS9_ art/runtime/jni/java_vm_ext.cc:1080:19 #3 0x7399a1b16c in JVM_NativeLoad art/openjdkjvm/OpenjdkJvm.cc:333:24
由于当前为非动态分区,且system分区大小为1.5G,开启ASAN/HWASAN后,编译的system.img超过了1.5G,因此需要按照如下修改(后续改成动态分区则不需要修改了)
partionvi device/jxx/shift/BoardConfig.mkifneq ($(strip $(BOARD_DYNAMIC_PARTITION_ENABLE)),true)#BOARD_BUILD_SYSTEM_ROOT_IMAGE := trueBOARD_VENDORIMAGE_PARTITION_SIZE := 1043333120 #1073741824ifeq ($(strip $(WITH_GMS)),true)BOARD_SYSTEMIMAGE_PARTITION_SIZE := 3093299200 #3221225472elseBOARD_SYSTEMIMAGE_PARTITION_SIZE := 3093299200 #1610612736endifBOARD_PRODUCTIMAGE_PARTITION_SIZE := 838860800ifeq ($(ENABLE_AB), true)AB_OTA_PARTITIONS ?= systemendifelse
烧录system时,提示无足够空间,因为当前ROM是4G,而system.img超过了1.5G,烧录system时,除了system.img,还剩余空间少于1.5G,因此失败,此时需要将system和vendor打包为super.img烧录
lpmake --metadata-size 65536 --super-name super --metadata-slots 3 --virtual-ab --device super:4294967296 \ --group Qti_dynamic_partitions_a:4290772992 --group qti_dynamic_partitions_b:4290772992 \ --partition system_a:readonly:$(get_build_var BOARD_SYSTEMIMAGE_PARTITION_SIZE):qti_dynamic_partitions_a --image system_a=$OUT/system.img \ --partition system_b:readonly:0:qti_dynamic_partitions_b \ --partition system_ext_a:readonly:0:qti_dynamic_partitions_a \ --partition system_ext_b:readonly:0:qti_dynamic_partitions_b \ --partition product_a:readonly:0:qti_dynamic_partitions_a \ --partition product_b:readonly:0:qti_dynamic_partitions_b \ --partition vendor_a:readonly:$(get_build_var BOARD_VENDORIMAGE_PARTITION_SIZE):qti_dynamic_partitions_a --image vendor_a=$OUT/vendor.img \ --partition vendor_b:readonly:0:qti_dynamic_partitions_b \ --sparse --output $OUT/super.img
fastboot flash super super.img
由于文件系统的不同,烧录userdata会导致系统无法启动,因此在烧录特殊版本的ASAN时,不烧录userdata.img,待system、vendor烧录启动后,push $OUT/data/asan到板卡的data目录下即可
来源地址:https://blog.csdn.net/jingerppp/article/details/131322020
--结束END--
本文标题: ASan和HWAsan在Android中使用
本文链接: https://lsjlt.com/news/393175.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-01-21
2023-10-28
2023-10-28
2023-10-27
2023-10-27
2023-10-27
2023-10-27
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0