Original address: http://android-developers.blogspot.com/2016/05/hardening-media-stack.html
Posted by Dan Austin and Jeff Vander Stoep, Android Security Team
To make Android more secure, we encourage and reward the researchers who have discovered the vulnerabilities. In 2015, Google fixed a series of bugs in MediaServer's libstagefright. We have released updates to these issues on security bulletin August 2015 and September.
In addition to the basic problem solving every month, we are also doing a new security feature to strengthen the existing security model and provide additional defense in depth. These defensive measures attempt to achieve two purposes:
- Prevention: fix bugs to prevent them from becoming a vulnerability
- Containment: Isolate components that handle untrusted content to protect the system
PreventionMost of the vulnerabilities found in Libstagefright are heap overflows caused by an unsigned integer overflow. Some integer overflows allow an attacker to allocate a buffer that is smaller than the actual amount of space needed to reach the data, causing a buffer overflow in the heap.
The result of unsigned integer overflow is very clear, but the subsequent behavior may be undesirable or unsafe. In contrast, a signed integer overflow is considered ambiguous in C + +, which means that the consequences of an overflow are not guaranteed, and the author of the compiler usually chooses the fastest or simplest from the consequences. We made changes to the compiler that would allow the compiler to provide a more secure default result when both signed and unsigned integer overflows.
Undefinedbehaviorsanitizer (Ubsan) is part of the Llvm/clang compiler toolchain to detect undefined or unexpected behavior. Ubsan checks for multiple types of undefined and unsafe behavior, including signed and unsigned integer overflows. These tests add code to the executable file and detect an integer overflow at run time. For example, Figure 1 shows the source code for the Parsechunk function of the Mpeg4extractor control that the original researcher patched after Libstagefright. This modification, included in the black box in the diagram, appears to prevent an integer overflow. Unfortunately, Size_max and SIZE are 32-bit values, Chunk_size are 64-bit values, which results in incomplete detection and potential integer overflows. In the red box, the addition of size and chunk_size may cause an integral type overflow and create a buffer smaller than the size element. Subsequent memcpy operations can cause a crash of available memory because the size+chunk_size in the blue box may be smaller than size. For a detailed description of the mechanism of the potential utilization vectors for this vulnerability, see Project Zero.
Figure 1: The source code shows a subtle unsigned integer overflow
Figure 2 compares the assembly language generated by the above code snippet with the second version compiled with the integer sanitization enabled. Figure 2 The Red box is an additive operation that causes an integer overflow.
In the unsanitized version, size (R6) and Chunk_size (R7) add up, potentially causing R0 to overflow and less than size. The buffer that should be allocated by size is specified as the size of R0, and then a size bit is copied into the R0-sized buffer. If R0 is smaller than size (R6), this can cause a memory crash.
in the sanitized version, size (R7) and Chunk_size (R5) are added together, and the results are stored in R0. Then, R0 and R7 compare, if R0 is less than R7, the program will point to the CC case code, R3 is set to 1. If the R3 is 1 and the execution bit is set, a memory overflow occurs and an abnormal termination is triggered to avoid a memory crash.
Note that incomplete detections caused by patches are not included in Figure 2. Overflow occurs at buffer allocation when the addition operation. The increased triggering operation in the sanitized version translates the exploited vulnerability into a harmless exception termination.
Although integral type Sanitizer was originally used as a code cleansing tool, they effectively blocked most known libstagefright vulnerabilities. Starting an integer overflow check is only the first step. Identify and fix integer overflows (mostly non-exploited) to prevent abnormal termination at runtime, which embodies the efforts of Android's media team. Most of the found overflows are fixed and the remaining (primarily performance reasons) are identified and marked as safe to prevent the runtime from terminating abnormally.
In Android N, the detection of signed and unsigned integer overflows can be performed throughout the media stack, including Libstagefright. This makes it more difficult to take advantage of integer overflows and also prevents the introduction of new integer overflow bugs in the future.
Containment in Android M and earlier versions, the MediaServer process is responsible for most of the multimedia-related tasks. This is thought to access all the permissions associated with these tasks, although it runs in its own sandbox, but it still needs to access a lot of resources and functionality. That's why libstagefright bugs at 2015 are significant--mediaserver can access some of the important resources on Android devices, including cameras, microphones, graphics cards, phones, Bluetooth and networking.
Root cause analysis indicates that libstagefright bugs mainly occur in the code that parses the file format and the multimedia decoder. It's not surprising that parsing complex file formats and encoders trying to accelerate is difficult, and a lot of edge situations make code vulnerable to accidental and malicious malformed input attacks.
However, multimedia parsers do not require access to most MediaServer-held permissions. For this reason, media Ream redesigned Android N's mediaserver, making it better to follow the principle of least privilege. Figure 3 shows how the entire block of MediaServer and its permissions are split, based on the following method:
- Parsing code is moved into a non-privileged sandbox that holds little or no permissions
- Components that require sensitive permissions are moved into the detach sandbox, which can access only the specific resources that the component requires. For example, only cameraserver may access the camera, only audioserver may access Bluetooth, and only drmserver may access the DRM resource.
Comparing Android N with earlier versions, the potential impact of Libstagefright bugs shows the value of this strategy. Allowing full block MediaServer access to all permissions and available resources (including graphics drivers, camera drivers, sockets, etc.) before obtaining Libstagefright executable code exposes a wide range of kernel attack surfaces.
In Android N, Libstagefright runs in a multimedia encoder sandbox that can only access very few permissions. SELinux blocks the loading of cameras, microphones, pictures, phones, Bluetooth, network access, and dynamic code. Seccomp further restricts interaction with the kernel. This means that libstagefright reduces the amount of privileges that an attacker can access by reducing the attack surface exposed by the kernel, and also slows the privilege increase.
Conclusion This multimedia hardening project is an ongoing effort that focuses on moving functionality into low-privilege sandboxes and further reducing the permissions granted to these sandboxes. Although the technology discussed here is used in the Android multimedia framework, it is also available for Android code libraries. These hardening technologies or other technologies are actively being applied to other components of Android.
Hardening the media stack