MTE(Memory Tag)是ARMV8.5增加一个硬件特性,主要用于内存安全。通过硬件Arch64 MTE和compiler辅助,可以增加64bit进程的内存安全。Android平台目前也开始使用MTE技术增加内存安全及其发现内存BUG。这个里面刚开始会看到很多相关的技术,但是之间的依赖关系是什么,怎么使用不是很特别清晰,简单梳理一下关系。
Memory Tag通俗讲就是为每个分配内存都打上一个TAG,当通过指针地址访问内存的时候,硬件会比较指针里面的TAG与实际内存TAG是否匹配,如果不匹配则检测出错误。
address tag:保存在64bit地址的最高8bit,作为开锁的钥匙key(访问内存),tag size被称为TS,一般是4bit或者8bit
Address/Pointer TAG
memory tag:一块被Lock的内存区域,Tagging memory implements the lock。被锁定的内存区域粒度被称为TG,大小一般是16字节/32字节/64字节,取决于硬件设置。ARM MTE为TS/TG=4bit/16bytes。如何锁定或者关联TAG到内存区域? 是通过芯片提供的指令来完成:
指令 | 含义 |
---|---|
LDG, STG, and STZG | getting or setting tags in memory |
ST2G and STZ2G | operate on two granules of memory |
STGP | stores both tag and data to memory. |
ADDG and SUBG | creating the addresses of objects on the stack. |
… |
存储Memory Tag的storage区域大小: TS extra bits per every TG bytes。
如何使用MTE对内存进行保护,简单描述如下:
使能不同内存类型的方式:
3.1 HWAddressSanitizer
目前HWAddressSanitizer实现,其实并不依赖硬件MTE支持,只需要硬件支持TBI(ARMv8 feature top byte ignore)即可,是基于一种软件模拟的MTE的做法。
Memory TAG存储在Memory Shadow区域,对应asan工具需要1/8内存,而hwasan工具只需要1/16内存存储关联的TAG即可。所有的Memory Access仍旧使用编译器插桩实现检测地址tag和memory tag是否匹配。
对于未来支持MTE的硬件,原则上不再需要运行库支持了,只需要编译器插入对应的Memory TAG指令即可实现安全内存检查。
3.2 Android Tagged Pointers
在malloc/free/calloc/realloc流程上实现heap tag功能,目前实现了在分配的heap地址上打上TAG:
//libc/bionic/malloc_tagged_pointers.h
//提供了一组函数
TagPointer,
UntagPointer,
MaybeUntagAndCheckPointer,
MaybeTagPointer,
//libc/bionic/heap_tagging.cpp
//libc/bionic/heap_tagging.h
SetDefaultHeapTaggingLevel:设置缺省的tag level
SetHeapTaggingLevel:设置缺省的TAG level
//libc/bionic/malloc_common.cpp
//TAG/UNTAG
calloc/free/malloc/...
<< · Back Index ·>>