硬件抽象层 (HAL) 在与设备无关的代码和特定于设备的硬件实现之间提供了一个接口。HAL 通常打包成共享库,直接加载到需要与硬件交互的进程中。安全边界在进程级实施。因此,将 HAL 加载到进程中意味着 HAL 与加载它的进程运行在相同的安全环境中。
传统的在进程中运行 HAL 的方法意味着进程需要每个进程中 HAL 所需的权限,包括对内核驱动程序的直接访问权限。同样,进程中的所有 HAL 都有与进程中其他 HAL 相同的一组权限,包括其他进程中 HAL 所需的权限。这就导致进程和 HAL 拥有过多的权限,能够访问它们本不应该访问的权限和硬件。
▲ 传统的一个进程中加载多个 HAL 的方法。
将 HAL 移到自己的进程中更好地遵循了最低权限原则。这带来了两个特别的好处:
每个 HAL 都在其自己的沙盒中运行,并且仅被允许访问它所控制的硬件驱动程序,而授予进程的权限仅限于完成其作业所必须的权限。
类似地,进程丧失了对 HAL 所需的硬件驱动程序、其他权限和功能的访问权。
▲ 每个 HAL 都运行在自己的进程中。
将 HAL 移到自己的进程中对于确保安全性非常有效,但其代价是客户端与 HAL 之间的 IPC 开销增大。对 Binder 驱动程序的改进使得 HAL 和客户端之间的 IPC 开销不再高不可攀。通过将 scatter-gather 引入 Binder,不再需要执行序列化/反序列化步骤,将对数据执行的复制操作次数从三次减少到一次,因而提高了每个事务的性能。Android O 还引入了 Binder 域,为供应商和平台组件提供独立的通信流。应用和 Android 框架继续使用 /dev/binder,但供应商提供的组件现在使用 /dev/vndbinder。平台和供应商组件之间的通信必须使用 /dev/hwbinder。在平台与供应商组件之间禁止其他形式的 IPC。
案例研究:系统服务器
由核心 Android OS 为应用提供的许多服务现在由系统服务器提供。随着 Android 不断发展壮大,系统服务器的责任和权限使其成为攻击者眼中的香饽饽。在 Treble 项目中,大约从系统服务器中剥离出 20 个 HAL,包括用于传感器、GPS、指纹、WLAN 等的 HAL。在此之前,一旦侵入上述任何 HAL,即可获得系统特权,但在 Android O 中,获得的权限将仅限于指定 HAL 所需的权限子集。
案例研究:媒体框架
在 Android O 中,延续了在 Android Nougat 中加固媒体栈的努力。在 Nougat 中,媒体服务器被划分成多个组件,以便更好地遵循最低权限原则,其中,只有音频服务器才享有音频硬件访问权,只有相机服务器才享有相机硬件访问权,等等。在 Android O 中,大多数直接硬件访问已从媒体框架中完全移除。例如,用于音频、相机和 DRM 的 HAL 已分别从音频服务器、相机服务器和 DRM 服务器中移除。