Android平台HWASan使用介绍
Hardware Address Sanitizer (HWASan)是应在开发期间使用的内存 bug 检测工具。对于 arm64,建议使用 HWASan;对于 32 位 arm 和非 Arm 平台,建议使用 ASan。两者提供的功能相同,并且都应当用于检测用户空间代码中的内存安全 bug。
如何启用HWASan
在Android系统编译时加入如下配置:
SANITIZE_TARGET=hwaddress
在Rockchip的Android11及以上平台的修改如下:(在device下面的产品目录的BoardConfig.mk中修改)
Android13_29_sdk/device/rockchip/rk3588$ git diff
diff --git a/BoardConfig.mk b/BoardConfig.mk
old mode 100644
new mode 100755
index 5a6cb59..47db367
--- a/BoardConfig.mk
+++ b/BoardConfig.mk
@@ -128,3 +129,6 @@ BOARD_BASEPARAMETER_SUPPORT := true
#pcie ethernet
PRODUCT_HAVE_PCIE_ETHERNET := true
+SANITIZE_TARGET=hwaddress
修改后完整编译Android并烧写固件即可。
了解 HWASan 报告
当 HWASan 工具检测到内存 bug 时,系统会通过 abort() 终止该进程,并将报告输出到 stderr 和 logcat。与 Android 上的所有原生代码崩溃问题一样,HWASan 错误也可以在 /data/tombstones 下找到。
与常规原生代码崩溃不同的是,HWASan 会在 Tombstone 顶部附近的“Abort message”字段中包含额外信息。请参阅下面基于堆的崩溃示例
示例报告
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'google/flame_hwasan/flame:Tiramisu/MASTER/7956676:userdebug/dev-keys'
Revision: 'DVT1.0'
ABI: 'arm64'
Timestamp: 2019-04-24 01:13:22+0000
pid: 11154, tid: 11154, name: sensors@1.0-ser >>> /vendor/bin/hw/android.hardware.sensors@1.0-service <<<
signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr --------
Abort message: '==9569==ERROR: HWAddressSanitizer: tag-mismatch on address 0x00433ae20045 at pc 0x00623ae2a9cc
READ of size 1 at 0x00433ae20045 tags: 5b/83 (ptr/mem) in thread T0
#0 0x7240450c68 (/system/lib64/vndk-sp-R/libcutils.so+0x8c68)
#1 0x723dffd490 (/vendor/lib64/sensors.ssc.so+0x34490)
#2 0x723e0126e0 (/vendor/lib64/sensors.ssc.so+0x496e0)
[...]
[0x00433ae20040,0x00433ae20060) is a small unallocated heap chunk; size: 32 offset: 5
Cause: use-after-free
0x00433ae20045 is located 5 bytes inside of 10-byte region [0x00433ae20040,0x00433ae2004a)
freed by thread T0 here:
#0 0x72404d1b18 (/system/lib64/libclang_rt.hwasan-aarch64-android.so+0x10b18)
#1 0x723af23040 (/vendor/lib64/libgralloccore.so+0x5040)
#2 0x723af23fa4 (/vendor/lib64/libgralloccore.so+0x5fa4)
[...]
previously allocated here:
#0 0x72404ce554 (/system/lib64/libclang_rt.hwasan-aarch64-android.so+0xd554)
#1 0x7240115654 (/apex/com.android.runtime/lib64/bionic/libc.so+0x43654)
#2 0x7240450ac8 (/system/lib64/vndk-sp-R/libcutils.so+0x8ac8)
[...]
hwasan_dev_note_heap_rb_distance: 1 1023
hwasan_dev_note_num_matching_addrs: 0
hwasan_dev_note_num_matching_addrs_4b: 0
Thread: T0 0x006a00002000 stack: [0x007fc1064000,0x007fc1864000) sz: 8388608 tls: [0x00737702ffc0,0x007377033000)
Memory tags around the buggy address (one tag corresponds to 16 bytes):
0x006f33ae1f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x006f33ae1f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x006f33ae1fa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x006f33ae1fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x006f33ae1fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x006f33ae1fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x006f33ae1fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x006f33ae1ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x006f33ae2000: 08 00 08 00 [83] 00 00 00 00 00 00 00 00 00 00 00
0x006f33ae2010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x006f33ae2020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x006f33ae2030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x006f33ae2040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x006f33ae2050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x006f33ae2060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x006f33ae2070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x006f33ae2080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Tags for short granules around the buggy address (one tag corresponds to 16 bytes):
0x006f33ae1ff0: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
=>0x006f33ae2000: 72 .. d0 .. [..] .. .. .. .. .. .. .. .. .. .. ..
0x006f33ae2010: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
See https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html#short-granules for a description of short granule tags
Registers where the failure occurred (pc 0x00623ae2a9cc):
x0 0000007fc18623ec x1 5b0000433ae20045 x2 0000000000000013 x3 ffffffffffffffff
x4 ffffffffffffffff x5 0000007fc1861da3 x6 6f7420676e696f47 x7 45522061206f6420
x8 0000000000000000 x9 0200006b00000000 x10 00000007fc18623f x11 5b0000433ae20040
x12 6f64206f7420676e x13 0a44414552206120 x14 0000000000000010 x15 ffffffffffffffff
x16 000000737169ac94 x17 0000000000000007 x18 0000007377bd8000 x19 0000007fc1862498
x20 0200006b00000000 x21 0000007fc18624a8 x22 0000000000000001 x23 0000000000000000
x24 0000000000000000 x25 0000000000000000 x26 0000000000000000 x27 0000000000000000
x28 0000000000000000 x29 0000007fc1862410 x30 000000623ae2a9d0 sp 0000007fc18623d0
SUMMARY: HWAddressSanitizer: tag-mismatch (/system/lib64/vndk-sp-R/libcutils.so+0x8c68)
[ … regular crash dump follows …]
这与 AddressSanitizer 报告非常类似。 不同的是,几乎所有 HWASan bug 都是“标记不匹配”,即在访问内存时,指针标记与相应的内存标记不匹配。原因可能是以下几项之一:
- 对堆栈或堆的访问出界:out of bounds access on stack or heap
- 对堆的释放后使用:use after free on heap
- 对堆栈的返回后使用:use after return on stack
Sections
以下是对 HWASan 报告各个部分的说明:
Access Error
包含与错误的内存访问有关的信息,其中包括:
- 访问类型(“读取”与“写入”)Access Type (“READ” vs. “WRITE”)
- 访问大小(尝试访问的字节数) Access size (how many bytes were attempted to be accessed)
- 访问的线程数 Thread number of the access
- 指针标记和内存标记(用于高级调试)Pointer and memory tags (for advanced debugging)
Access Stack Trace
错误的内存访问的堆栈轨迹。
Cause
造成访问错误的潜在原因。如果有多种候选原因,这些原因会按可能性降序排列,后跟有关潜在原因的详细信息。HWASan 可以诊断以下原因:
- 释放后使用 use-after-free
- 堆栈标记不匹配:可能是堆栈返回后使用/范围外使用或出界 stack tag-mismatch: this can be stack use-after-return / use after-scope, or out of bounds
- 堆缓冲区溢出 heap-buffer-overflow
- 全局溢出 global-overflow
Memory Information
描述 HWASan 对所访问内存的了解,可能会因 bug 类型而异。
bug 类型 | 原因 | 报告格式 |
---|---|---|
tag-mismatch | use-after-free | <address> is located N bytes inside of M-byte region [, ) freed by thread T0 here: |
tag-mismatch | heap-buffer-overflow | <address> is located N bytes to the right of M-byte region [<start>, <end>) allocated here: |
tag-mismatch | stack tag-mismatch | 堆栈报告不会区分上溢/下溢和“返回后使用”bug。此外,如需查找作为错误来源的堆栈分配,需要执行离线符号化步骤。请参阅下面的了解堆栈报告部分。 |
invalid-free | use-after-free | 这是一个重复释放 bug。 <address> is located N bytes inside of M-byte region [<start>, <end>) freed by thread T0 here: |
invalid-free | cannot describe address | 从 HWASan 的可用缓冲区中逐出错误释放(之前未分配的内存释放)或分配内存后的重复释放。 |
invalid-free | 0x… is HWAsan shadow memory | 这显然是错误释放,因为应用尝试释放的是 HWASan 内部的内存。 |
Deallocation Stack Trace
在取消分配内存情况下的堆栈轨迹。仅适用于“释放后使用”或“无效释放”bug。
Allocation Stack Trace
在分配内存情况下的堆栈轨迹。
dump信息反编译
如需获取堆栈轨迹中的函数名称和行号(以及获取“范围外使用”bug 的变量名称),需要执行离线符号化步骤。
llvm-symbolizer工具
llvm-symbolizer工具可以用来进行反编译,该工具可以在clang的目录下找到,如下:
~/a2_Android13_29_sdk$ find prebuilts/clang -name hwasan_symbolize
prebuilts/clang/host/linux-x86/clang-r450784d/lib64/clang/14.0.6/lib/linux/x86_64-linux-musl/bin/hwasan_symbolize
prebuilts/clang/host/linux-x86/clang-r450784d/lib64/clang/14.0.6/bin/hwasan_symbolize
~/a2_Android13_29_sdk$
使用与你编译时使用的clang版本下的hwasan_symbolize即可。
反编译符号表
为了进行符号化处理,我们需要包含符号的未剥离版二进制文件。这类文件的位置取决于 build 类型:
针对本地 build,符号文件可在 out/target/product//symbols/ 中找到,如:
out/target/product/rk3588_t/symbols/
符号化处理:
prebuilts/clang/host/linux-x86/clang-r450784d/lib64/clang/14.0.6/bin/hwasan_symbolize out/target/product/rk3399_t/symbols/ < dump.txt
其中dump.txt保存的是HWASan的crash信息
了解堆栈报告
针对堆栈变量出现的 bug,HWASan 报告将包含如下详细信息:
Cause: stack tag-mismatch
Address 0x007d4d251e80 is located in stack of thread T64
Thread: T64 0x0074000b2000 stack: [0x007d4d14c000,0x007d4d255cb0) sz: 1088688 tls: [0x007d4d255fc0,0x007d4d259000)
Previously allocated frames:
record_addr:0x7df7300c98 record:0x51ef007df3f70fb0 (/apex/com.android.art/lib64/libart.so+0x570fb0)
record_addr:0x7df7300c90 record:0x5200007df3cdab74 (/apex/com.android.art/lib64/libart.so+0x2dab74)
[...]
为了让堆栈 bug 易于理解,HWASan 会跟踪过去出现的堆栈帧。 目前,HWASan 不会在 bug 报告中将此类内容转换为人类可理解的内容,而是需要额外的符号化步骤。
问题排查
“HWAddressSanitizer can not describe address in more detail.”
有时,HWASan 可能会因与过去的内存分配相关的信息而用尽空间。在这种情况下,报告将仅包含一条即时内存访问的堆栈轨迹,后跟备注:
HWAddressSanitizer can not describe address in more detail.
在某些情况下,可通过多次运行测试来解决此问题。另一种方法是增加 HWASan 历史记录大小。此操作可以在 build/soong/cc/sanitize.go 中(查找 hwasanGlobalOptions)或您的进程环境中(可使用 adb shell echo $HWASAN_OPTIONS 查看当前设置)全局执行。
“nested bug in the same thread”
这意味着在生成 HWASan 崩溃报告时出现了 bug。这通常是因为 HWASan 运行时中存在 bug,请提交 bug 并尽可能提供有关如何重现该问题的说明。文章来源:https://www.toymoban.com/news/detail-627470.html
本文参考:https://source.android.com/docs/security/test/memory-safety/hwasan-reports?hl=zh-cn文章来源地址https://www.toymoban.com/news/detail-627470.html
到了这里,关于Android平台HWASan使用介绍的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!