Author: geneblue
Blog: https://geneblue.github.io/
前几天,Google 正式发布了 Android 8.0。 没错,真的就叫 OREO(奥利奥)。
运行于 Andorid 8.0 的内核会增加几点安全特性,主要用于缓解内核漏洞和内核驱动 bug。 这些特性已经更新在 kernel/common 源码的 android-3.18,android-4.4 和 android-4.9 分支中。
0x01 新增安全特性
Hardened usercopy
CONFIG_HARDENED_USERCOPY=y
内核经常通过 copy_from_user()/copy_to_user()
读写用户态空间,但这对函数没有边界检查(或者说开发者们没有做好边界检查),如果能够控制相关参数,就可以大量覆盖内核空间或者大量泄漏内核内存。前者如果能覆盖到比较重要的内核对象,就极易导致任意代码执行;后者就是典型的内核信息泄漏了。
针对这个问题,Linux 内核加固补丁集项目 Grsecurity 增加了 PAX_USERCOPY 特性来增强这两个函数。该补丁主要关注这两个函数的内核指针参数,对内核指针做一系列检查,主要包括不允许为null,不允许指向 kmalloc() 0 长度时分配的地址,不允许指向内核代码段,如果指向已分配的内核堆,确保拷贝内容大小要在已分配对象的大小之内,如果拷贝涉及内核栈,拷贝内容的大小要在当前进程的内核栈中。还有其他的一些检查,针对不同架构也有一些差异,具体细节,参见Hardened usercopy。
arm/arm64 PAN
1 | CONFIG_CPU_SW_DOMAIN_PAN=y |
PAN(Privileged Access Never) 可以认为是 PXN(Privileged eXecute Never) 的增强版,用于阻止内核直接访问用户空间。PXN 不允许内核执行用户态代码,PAN 直接不允许内核访问用户空间数据,进一步隔离内核空间与用户空间。
KASLR
CONFIG_RANDOMIZE_BASE=y
KASLR(Kernel Address Space Layout Randomization) 用于随机化内核的内存地址,在 4.4 和之后的内核中,将会默认使用。 内核符号不再固定,这无疑影响内核提权。比较普遍的解决办法是,先通过信息泄漏漏洞获取一些内核地址,然后再计算出关注的内核符号地址。方法也不是绝对的,没准哪天就爆出一个直接绕过 KASLR 的漏洞。
在 Android 阵营中,三星手机的安全性比较高,目前已经有一些机器在使用 KASLR 了。
0x02 其他安全特性
Android 8.0 也将继续支持正在使用的安全特性
1 | 栈溢出缓解:CONFIG_CC_STACKPROTECTOR_STRONG=y |