1page.title=Media Framework Hardening 2@jd:body 3 4<!-- 5 Copyright 2016 The Android Open Source Project 6 7 Licensed under the Apache License, Version 2.0 (the "License"); 8 you may not use this file except in compliance with the License. 9 You may obtain a copy of the License at 10 11 http://www.apache.org/licenses/LICENSE-2.0 12 13 Unless required by applicable law or agreed to in writing, software 14 distributed under the License is distributed on an "AS IS" BASIS, 15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 See the License for the specific language governing permissions and 17 limitations under the License. 18--> 19<div id="qv-wrapper"> 20 <div id="qv"> 21 <h2>In this document</h2> 22 <ol id="auto-toc"> 23 </ol> 24 </div> 25</div> 26 27<p>To improve device security, Android 7.0 breaks up the monolithic 28<code>mediaserver</code> process into multiple processes with permissions and 29capabilities restricted to only those required by each process. These changes 30mitigate media framework security vulnerabilities by:</p> 31<ul> 32<li>Splitting AV pipeline components into app-specific sandboxed processes.</li> 33<li>Enabling updatable media components (extractors, codecs, etc.).</li> 34</ul> 35 36<p>These changes also improve security for end users by significantly reducing 37the severity of most media-related security vulnerabilities, keeping end user 38devices and data safe.</p> 39 40<p>OEMs and SoC vendors need to update their HAL and framework changes to make 41them compatible with the new architecture. Specifically, because vendor-provided 42Android code often assumes everything runs in the same process, vendors must 43update their code to pass around native handles (<code>native_handle</code>) 44that have meaning across processes. For a reference implementation of changes 45related to media hardening, refer to <code>frameworks/av</code> and 46<code>frameworks/native</code>.</p> 47 48<h2 id=arch_changes>Architectural changes</h2> 49<p>Previous versions of Android used a single, monolithic 50<code>mediaserver</code> process with great many permissions (camera access, 51audio access, video driver access, file access, network access, etc.). Android 527.0 splits the <code>mediaserver</code> process into several new processes that 53each require a much smaller set of permissions:</p> 54 55<p><img src="images/ape_media_split.png" alt="mediaserver hardening"></p> 56<p class="img-caption"><strong>Figure 1.</strong> Architecture changes for 57mediaserver hardening</p> 58 59<p>This new architecture ensures that even if a process is compromised, 60malicious code does not have access to the full set of permissions previously 61held by mediaserver. Processes are restricted by SElinux and seccomp policies. 62</p> 63 64<p class=note><strong>Note:</strong> Because of vendor dependencies, some codecs 65still run in the <code>mediaserver</code> and consequently grant 66<code>mediaserver</code> more permissions than necessary. Specifically, Widevine 67Classic continues to run in the <code>mediaserver</code> for Android 7.0.</p> 68 69<h3 id=mediaserver-changes>MediaServer changes</h3> 70<p>In Android 7.0, the <code>mediaserver</code> process exists for driving 71playback and recording, e.g. passing and synchronizing buffers between 72components and processes. Processes communicate through the standard Binder 73mechanism.</p> 74<p>In a standard local file playback session, the application passes a file 75descriptor (FD) to <code>mediaserver</code> (usually via the MediaPlayer Java 76API), and the <code>mediaserver</code>:</p> 77<ol> 78<li>Wraps the FD into a Binder DataSource object that is passed to the extractor 79process, which uses it to read from the file using Binder IPC. (The 80mediaextractor doesn't get the FD but instead makes Binder calls back to the 81<code>mediaserver</code> to get the data.)</li> 82<li>Examines the file, creates the appropriate extractor for the file type 83(e.g. MP3Extractor, or MPEG4Extractor), and returns a Binder interface for the 84extractor to the <code>mediaserver</code> process.</li> 85<li>Makes Binder IPC calls to the extractor to determine the type of data in the 86file (e.g. MP3 or H.264 data).</li> 87<li>Calls into the <code>mediacodec</code> process to create codecs of the 88required type; receives Binder interfaces for these codecs.</li> 89<li>Makes repeated Binder IPC calls to the extractor to read encoded samples, 90uses the Binder IPC to send encoded data to the <code>mediacodec</code> process 91for decoding, and receives decoded data.</li> 92</ol> 93<p>In some use cases, no codec is involved (such as an offloaded playback where 94encoded data is sent directly to the output device), or the codec may render the 95decoded data directly instead of returning a buffer of decoded data (video 96playback).</p> 97 98<h3 id=mediacodecservice_changes>MediaCodecService changes</h3> 99<p>The codec service is where encoders and decoders live. Due to vendor 100dependencies, not all codecs live in the codec process yet. In Android 7.0:</p> 101<ul> 102<li>Non-secure decoders and software encoders live in the codec process.</li> 103<li>Secure decoders and hardware encoders live in the <code>mediaserver</code> 104(unchanged).</li> 105</ul> 106 107<p>An application (or mediaserver) calls the codec process to create a codec of 108the required type, then calls that codec to pass in encoded data and retrieve 109decoded data (for decoding) or to pass in decoded data and retrieve encoded data 110(for encoding). Data transfer to and from codecs uses shared memory already, so 111that process is unchanged.</p> 112 113<h3 id=mediadrmserver_changes>MediaDrmServer changes</h3> 114<p>The DRM server is used when playing DRM-protected content, such as movies in 115Google Play Movies. It handles decrypting the encrypted data in a secure way, 116and as such has access to certificate and key storage and other sensitive 117components. Due to vendor dependencies, the DRM process is not used in all cases 118yet.</p> 119 120<h3 id=audioserver_changes>AudioServer changes</h3> 121<p>The AudioServer process hosts audio related components such as audio input 122and output, the policymanager service that determines audio routing, and FM 123radio service. For details on Audio changes and implementation guidance, see 124<a href="{@docRoot}devices/audio/implement.html">Implementing Audio</a>.</p> 125 126<h3 id=cameraserver_changes>CameraServer changes</h3> 127<p>The CameraServer controls the camera and is used when recording video to 128obtain video frames from the camera and then pass them to 129<code>mediaserver</code> for further handling. For details on changes and 130implementation guidance for CameraServer changes, refer to 131<a href="{@docRoot}devices/camera/versioning.html#hardening">Camera Framework 132Hardening</a>.</p> 133 134<h3 id=extractor_service_changes>ExtractorService changes</h3> 135<p>The extractor service hosts the <em>extractors</em>, components that parse 136the various file formats supported by the media framework. The extractor service 137is the least privileged of all the services—it can't read FDs so instead 138it makes calls onto a Binder interface (provided to it by the 139<code>mediaserver for</code> each playback session) to access files.</p> 140<p>An application (or <code>mediaserver</code>) makes a call to the extractor 141process to obtain an <code>IMediaExtractor</code>, calls that 142<code>IMediaExtractor</code> to obtain<code> IMediaSources</code> for the track 143contained in the file, and then calls <code>IMediaSources</code> to read data 144from them.</p> 145<p>To transfer the data between processes, the application (or 146<code>mediaserver</code>) includes the data in the reply-Parcel as part of the 147Binder transaction or uses shared memory:</p> 148 149<ul> 150<li>Using <strong>shared memory</strong> requires an extra Binder call to 151release the shared memory but is faster and uses less power for large buffers. 152</li> 153<li>Using <strong>in-Parcel</strong> requires extra copying but is faster and 154uses less power for buffers smaller than 64KB.</li> 155</ul> 156 157<h2 id=implementation>Implementation</h2> 158<p>To support the move of <code>MediaDrm</code> and <code>MediaCrypto</code> 159components into the new <code>mediadrmserver</code> process, vendors must change 160the allocation method for secure buffers to allow buffers to be shared between 161processes.</p> 162<p>In previous Android releases, secure buffers are allocated in 163<code>mediaserver</code> by <code>OMX::allocateBuffer</code> and used during 164decryption in the same process, as shown below:</p> 165 166<p><img src="images/ape_media_buffer_alloc_pren.png"></p> 167<p class="img-caption"><strong>Figure 2.</strong> Android 6.0 and lower buffer 168allocation in mediaserver.</p> 169 170<p>In Android 7.0, the buffer allocation process has changed to a new mechanism 171that provides flexibility while minimizing the impact on existing 172implementations. With <code>MediaDrm</code> and <code>MediaCrypto</code> stacks 173in the new <code>mediadrmserver</code> process, buffers are allocated 174differently and vendors must update the secure buffer handles so they can be 175transported across binder when <code>MediaCodec</code> invokes a decrypt 176operation on <code>MediaCrypto</code>.</p> 177 178<p><img src="images/ape_media_buffer_alloc_n.png"></p> 179<p class="img-caption"><strong>Figure 3.</strong> Android 7.0 and higher buffer 180allocation in mediaserver.</p> 181 182<h3 id=native_handles>Using native handles</h3> 183<p>The <code>OMX::allocateBuffer</code> must return a pointer to a 184<code>native_handle</code> struct, which contains file descriptors (FDs) and 185additional integer data. A <code>native_handle</code> has all of the advantages 186of using FDs, including existing binder support for 187serialization/deserialization, while allowing more flexibility for vendors who 188don't currently use FDs.</p> 189<p>Use <code>native_handle_create()</code> to allocate the native handle. 190Framework code takes ownership of the allocated <code>native_handle</code> 191struct and is responsible for releasing resources in both the process where 192the <code>native_handle</code> is originally allocated and in the process where 193it is deserialized. The framework releases native handles with 194<code>native_handle_close()</code> followed by 195<code>native_handle_delete()</code> and serializes/deserializes the 196<code>native_handle</code> using 197<code>Parcel::writeNativeHandle()/readNativeHandle()</code>. 198</p> 199<p>SoC vendors who use FDs to represent secure buffers can populate the FD in 200the <code>native_handle</code> with their FD. Vendors who don't use FDs can 201represent secure buffers using additional fields in the 202<code>native_buffer</code>.</p> 203 204<h3 id=decrypt_location>Setting decryption location</h3> 205<p>Vendors must update the OEMCrypto decrypt method that operates on the 206<code>native_handle</code> to perform any vendor-specific operations necessary 207to make the <code>native_handle</code> usable in the new process space (changes 208typically include updates to OEMCrypto libraries).</p> 209<p>As <code>allocateBuffer</code> is a standard OMX operation, Android 7.0 210includes a new OMX extension 211(<code>OMX.google.android.index.allocateNativeHandle</code>) to query for this 212support and an <code>OMX_SetParameter</code> call that notifies the OMX 213implementation it should use native handles.</p> 214