11

修志龙_ZenonXiu · 2022年10月12日 · 上海市浦东新区

如何在Android用上armv9 CPU的新功能

基于Armv9 CPU的手机芯片已经被广泛采用。如何在Android用上Armv9 CPU新引入的PAC,BTI, MTE安全特性和SVE2呢?
早在2020年,arm已经和google合作将这些新特性带入到Android 12, NDK r23也支持了PAC, BTI等。

1. 如何利用PAC, BTI 功能

a. Linux kernel

需要使用linux v5.10及以后的支持PAC,BTI的版本:
Kernel配置需要使能CONFIG_ARM64_PTR_AUTH=y, 这使能了user space的PAC支持。如果要使能kernel代码本身的PAC保护,需要使能ARM64_PTR_AUTH_KERNEL =y。
BTI的支持类似,需要使能CONFIG_ARM64_BTI和CONFIG_ARM64_BTI_KERNEL。
还需要支持PAC和BTI的GCC编译器。
因为Kernel可使用软件随机数来产生PAC的key, 支持PAC不需要SoC层面的支持。BTI的影响纯粹在CPU层面,更不需要SoC层面的支持。使能PAC和BTI非常便捷。

b. AOSP

需要在创建的device的makefile  device/<company-name>/<device-name>/ boardconfig.mk 选择合适的 TARGET_ARCH_VARIANT,如果要利用上PAC,BTI,需要设置TARGET_ARCH_VARIANT := armv8-a-branchprot 
这样编译AOSP时,https://android.googlesource....

Picture1.png

会选择NDK LLVM编译的选项为-mbranch-protection=standard, 此选项会让编译器编译出带PAC和BTI指令的库,可执行性文件。
如果通过llvm-readelf查看编译后的目标文件,可以看到这样的属性:

Properties:    aarch64 feature: BTI, PAC

c. 自有native程序,库

需要在项目对应的编译选项在加上

-mbranch-protection=standard

2.如何利用MTE

a. 硬件平台要求

  • 支持MTE的CPU
  • 支持MTE transaction的总线接口,如CHI-E总线
  • 支持MTE的互联(Interconnect),如CI-700(用来解释分拆MTE transaction,将MTE translation转换为对DRAM里用来存储MTE tag的内存区域的一般访问,optionally, CI-700可以有MTE cache来cache MTE tag访问)

b. Firmware的支持

  • 使能EL2, EL1, EL0对MTE tag访问
  • 如果使用如CI-700的互联,需要配置CI-700寄存器,以告知DRAM中存放MTE tag内存区域的地址信息

c. Linux Kernel

需要使能

CONFIG_ARM64_MTE=y, CONFIG_KASAN=y, CONFIG_KASAN_HW_TAGS=y

使kernel支持user space利用MTE

d. Android的支持

参见Google Android document:
https://source.android.com/do...

  • 对应heap-tagging(malloc,free)的支持,scudo库已经通过intrinsics支持,不需要额外的编译命令
    external/scudo/standalone/memtag.h

image.png

  • 对于每个进程是否要使用heap-tagging,使用synch或是async的MTE check模式,可以
    a) 对一个项目,可以在Android.bp中
    image.png
    例如在external/iptables/iptables/Android.bp 中
    image.png

或是Android.mk中
image.png

b) 使用product variable对source tree下的子目录
image.png
或是
image.png

通过llvm-readelf可以看到编译出来的目标文件具有

.note.android.memtag

属性

以上编译配置可以在运行时通过以下系统属性override

  arm64.memtag.process.<name> = (off | sync | async)

其中name是可执行文件的名字。

c)设置执行环境变量

MEMTAG_OPTIONS=(off|sync|async)

通过以上环境变量设置之后启动的native应用都按配置做MTE检查

d) 通过AndroidManifest.xml
通过AndroidManifest.xml下的<application> 或 <process>,设置

android:memtagMode=(off|default|sync|async)

例如在packages/modules/Bluetooth/android/app/AndroidManifest.xml中
image.png

e) 运行时设置
开发者可以通过调用

int mallopt(M_BIONIC_SET_HEAP_TAGGING_LEVEL, level)

动态控制MTE模式,level可以是

● M_HEAP_TAGGING_LEVEL_NONE
● M_HEAP_TAGGING_LEVEL_ASYNC
● M_HEAP_TAGGING_LEVEL_SYNC
  • 为Android image编译提供MTE的支持
    Google强烈建议在开发阶段为所有的native二进制使能MTE sync check, 可以通过设置环境变量

    SANITIZE_TARGET=memtag_heap SANITIZE_TARGET_DIAG=memtag_heap m
    

    这使除zygote64之外的native应用对进行MTE check.
    在build/make/core/config_sanitizers.mk中

3. 如何利用SVE2

a. Linux Kernel

需要使能CONFIG_ARM64_SVE=y, kernel本身不利用SVE,主要是save/restore SVE寄存器context, 并通过auxv HWCAP/HWCAP2告诉user space平台对SVE的支持。

b. AOSP

目前阶段AOSP项目本身还未使用SVE2,SVE2的优化还在持续进行中。

c. 自有应用/库

可以利用SVE2 intrinsics或内嵌汇编优化,并在项目编译选项中加入-march= … +sve2
比如arm compute library就已经有SVE/SVE2的支持,
https://github.com/ARM-softwa...
image.png

推荐阅读
关注数
8629
内容数
51
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息