Android平台HWASan使用介绍

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-mismatchuse-after-free<address> is located N bytes inside of M-byte region [, ) freed by thread T0 here:
tag-mismatchheap-buffer-overflow<address> is located N bytes to the right of M-byte region [<start>, <end>) allocated here:
tag-mismatchstack tag-mismatch堆栈报告不会区分上溢/下溢和“返回后使用”bug。此外,如需查找作为错误来源的堆栈分配,需要执行离线符号化步骤。请参阅下面的了解堆栈报告部分。
invalid-freeuse-after-free这是一个重复释放 bug。
<address> is located N bytes inside of M-byte region [<start>, <end>) freed by thread T0 here:
invalid-freecannot describe address从 HWASan 的可用缓冲区中逐出错误释放(之前未分配的内存释放)或分配内存后的重复释放。
invalid-free0x… 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://source.android.com/docs/security/test/memory-safety/hwasan-reports?hl=zh-cn

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

loitawu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值