Android 11 的系统升级

安全侠 2020-07-02
移动安全 发布于 2020-07-02 14:09:19 阅读 88 评论 0


在Android 11中,我们将继续提高Android平台的安全性。我们已经进行了更安全的默认设置,强化了内存分配器,并扩展了编译器缓解措施的使用,这些措施可防御各种漏洞,有利于开发。

初始化内存

我们已经在Android 11的用户空间和Linux内核中启用了自动内存初始化的形式。在C/ c++中,当没有初始化就使用内存时,会出现未初始化内存错误。这些错误的类型可能会混淆,甚至“未初始化”这个术语也会引起误解。未初始化似乎意味着变量有一个随机值。事实上,它不是随机的。它该内存地址之前存储的值。这个值可能是可预测的甚至可以被攻击者控制,这将会导致严重的漏洞,比如信息泄露漏洞像ASLR旁路,或者通过堆栈控制流拦截。使用未初始化值的另一个隐患是高级编译器优化可能会不可预测地转换代码,根据相关的C标准认为这是未定义的行为。

事实上,使用未初始化的内存是很难检测的。如果内存碰巧大多数时候都是用一些“安全”值初始化的,那么这些错误可能会在代码库中存在多年而不被注意。当未初始化内存导致错误时,通常很难确定错误的来源,特别是在很少触发错误的情况下。

消灭一整类这样的bug要比逐个消灭它们有效得多。自动栈变量初始化依赖于Clang编译器中的一个特性,该特性允许选择用零或模式初始化局部变量。

初始化值为零为字符串、指针、索引和大小提供了更安全的默认值。零初始化的缺点是返回值不太安全,使用零初始化值在底层漏洞中暴漏的bug更少。模式初始化可以暴露更多的bug,通常对返回值更安全,但对字符串、指针、索引和大小不安全。

初始化用户空间

自动栈变量初始化在整个Android用户空间都是启用的。在Android 11的开发过程中,我们最初选择模式初始化是为了发现依赖于零初始化的bug,但在几个月后为了提高安全性而改为零初始化。如果平台OS开发人员在找零初始化所产生的bug时,可以使用AUTO_PATTERN_INITIALIZE=true m

初始化内核

自动堆栈和堆初始化最近已在Linux内核中合并。我们已经在早期Android版本的内核中包括了这些功能。这将会强制执行局部变量和堆分配的初始化,攻击者无法控制这些已知值,并且在泄漏时无利用价值。这两个功能都会导致性能开销变大,但可以解决未定义情况,从而提高稳定性和安全性。

对于内核堆栈初始化,我们采用了Linux的CONFIG_INIT_STACK_ALL。它目前依赖于栈的Clang模式初始化。

堆初始化由两个启动时标志init_on_allocinit_on_free进行控制,前者使用零覆盖刚分配的堆对象(s/kmalloc/kzalloc以整个内核为单位),后者在对象释放之前执行覆盖(这有助于缩短安全敏感数据的生命周期)。init_on_alloc具有更好的缓存友好性,并且对性能的影响较小(在2%以内),因此已选择它来保护Android内核。

Scudo目前是Android默认的本机分配器

在Android 11中,Scudo代替jemalloc作为Android的默认本机分配器。Scudo是一个强化的内存分配器,旨在帮助检测和缓解堆中的内存损坏bug。

Scudo没有完全防止漏洞利用,但是它添加了一些健全性检查,这些检查可以有效地增强堆,以防止某些内存损坏bug。

它还通过降低分配模式的可预测性并按大小进行分配,从而以一种使内存破坏更难以利用的方式来主动组织堆。

在我们的内部测试中,Scudo已经通过以前未被检测到的bug证明了它的价值。

查找堆内存安全bug (GWP-ASan)

Android 11引入了GWP-ASan,这是一个直接集成到本地分配器Scudo中的堆内存安全bug检测工具。当堆内存安全bug发生时,GWP-ASan可以检测并提供可操作的报告,这些错误可在32位和64位计算机上运行,并且默认情况下通过系统进程和系统应用程序启用。

对于开发者应用程序,GWP-ASan也可以通过AndroidManifest中的一行选择进入。不需要复杂的构建支持,也不需要重新编译预构建的库。

基于软件标签的KASAN

在 Android 的Arm Memory Tagging Extension(MTE)方面,Android 11对内核HWASAN提供支持。自Android 10起支持用户空间HWASAN。

KernelAddressSANitizer (KASAN)是一个动态的内存错误检测器,旨在发现Linux内核中的出界和免费使用的错误。其基于软件标记的模式是内核内存标记概念的软件实现。基于软件标签的KASAN在4.14、4.19和5.4 Android内核中都有,可以通过CONFIG_KASAN_SW_TAGS内核配置选项启用。目前KASAN只支持平板存储器的标签;将来还将添加对其他类型内存(比如堆栈和全局内存)的支持。

与通用KASAN相比,基于标签的KASAN具有更低的内存要求,这使其可在狗粮测试设备上使用。基于软件标签的KASAN的另一个用例是检查现有内核代码与内存标签的兼容性。由于基于标记的KASAN与未来的内核 MTE支持基于类似的概念,因此确保内核代码与基于标记的KASAN将简化未来内核 MTE集成。

扩展现有的编译器缓解措施

我们还在继续扩展之前发布的编译器缓解措施。这包括在一些核心库中添加整型和边界杀毒,而这些核心库之前还缺乏这两种杀毒。例如,libminikin字体库和libui渲染库现在已经清除了边界。通过在这些组件中实现整数溢出杀毒软件和边界杀毒软件,我们增强了NFC栈。
除了像杀毒这样的硬性缓解措施之外,我们还继续扩大CFI的缓解措施。Android的网络守护进程、DNS解析器和其他核心javascript库如libv8和PacProcessor都启用了CFI。

软件编解码器沙箱的有效性

在Android 10发布之前,发布了一个新的受限沙箱用于软件编解码器。目前为止,Android 10是继Android 5.0中臭名昭著的stagefright漏洞之后的第一个Android版本,媒体框架中没有任何严重安全漏洞。

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!
请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!