Posted by Jeff Vander Stoep, Senior Software Engineer, Android Security
Updates are essential for security, but they can be difficult and expensive for device manufacturers. Project Treble is making updates easier by separating the underlying vendor implementation from the core Android framework. This modularization allows platform and vendor-provided components to be updated independently of each other. While easier and faster updates are awesome, Treble’s increased modularity is also designed to improve security.
A Hardware Abstraction Layer (HAL) provides an interface between device-agnostic code and device-specific hardware implementations. HALs are commonly packaged as shared libraries loaded directly into the process that requires hardware interaction. Security boundaries are enforced at the process level. Therefore, loading the HAL into a process means that the HAL is running in the same security context as the process it’s loaded into.
The traditional method of running HALs in-process means that the process needs all the permissions required by each in-process HAL, including direct access to kernel drivers. Likewise, all HALs in a process have access to the same set of permissions as the rest of the process, including permissions required by other in-process HALs. This results in over-privileged processes and HALs that have access to permissions and hardware that they shouldn’t.
Moving HALs into their own processes better adheres to the principle of least privilege. This provides two distinct advantages:
- Each HAL runs in its own sandbox and is permitted access to only the hardware driver it controls and the permissions granted to the process are limited to the permissions required to do its job.
- Similarly, the process loses access to hardware drivers and other permissions and capabilities needed by the HALs.
Moving HALs into their own processes is great for security, but it comes at the cost of increased IPC overhead between the client process and the HAL. Improvements to the binder driver made IPC between HALs and clients practical. Introducing scatter-gather into binder improves the performance of each transaction by removing the need for the serialization/deserialization steps and reducing the number of copy operations performed on data from three down to one. Android O also introduces binder domains to provide separate communication streams for vendor and platform components. Apps and the Android frameworks continue to use /dev/binder, but vendor-provided components now use /dev/vndbinder. Communication between the platform and vendor components must use /dev/hwbinder. Other means of IPC between platform and vendor are disallowed.
Case study: System Server
Many of the services offered to apps by the core Android OS are provided by the system server. As Android has grown, so has system server’s responsibilities and permissions, making it an attractive target for an attacker. As part of project Treble, approximately 20 HALs were moved out of system server, including the HALs for sensors, GPS, fingerprint, Wi-Fi, and more. Previously, a compromise in any of those HALs would gain privileged system permissions, but in Android O, permissions are restricted to the subset needed by the specific HAL.
Case study: media frameworks
Efforts to harden the media stack in Android Nougat continued in Android O. In Nougat, mediaserver was split into multiple components to better adhere to the principle of least privilege, with audio hardware access restricted to audioserver, camera hardware access restricted to cameraserver, and so on. In Android O, most direct hardware access has been entirely removed from the media frameworks. For example HALs for audio, camera, and DRM have been moved out of audioserver, cameraserver, and drmserver respectively.
Reducing and isolating the attack surface of the kernel
The Linux kernel is the primary enforcer of the security model on Android. Attempts to escape sandboxing mechanisms often involve attacking the kernel. An analysis of kernel vulnerabilities on Android showed that they overwhelmingly occurred in and were reached through hardware drivers.
De-privileging system server and the media frameworks is important because they interact directly with installed apps. Removing direct access to hardware drivers makes bugs difficult to reach and adds another layer of defense to Android’s security model.