媒體框架強化

為了提高裝置安全性,Android 7.0 將單一mediaserver進程分解為多個進程,權限和功能僅限於每個進程所需的權限和功能。這些變更透過以下方式緩解媒體框架安全漏洞:

  • 將 AV 管道組件拆分為特定於應用程式的沙盒進程。
  • 啟用可更新的媒體元件(提取器、編解碼器等)。

這些變更還透過顯著降低大多數媒體相關安全漏洞的嚴重性來提高最終用戶的安全性,從而保證最終用戶設備和資料的安全。

OEM 和 SoC 供應商需要更新其 HAL 和框架更改,以使其與新架構相容。具體來說,由於供應商提供的 Android 程式碼通常假設所有內容都在同一進程中運行,因此供應商必須更新其程式碼以傳遞跨進程有意義的本機句柄 ( native_handle )。有關與媒體增強相關的變更的參考實現,請參閱frameworks/avframeworks/native

架構變化

先前版本的 Android 使用單一整體mediaserver進程,具有大量權限(相機存取、音訊存取、視訊驅動程式存取、檔案存取、網路存取等)。 Android 7.0 將mediaserver進程拆分為幾個新進程,每個進程需要的權限要少得多:

媒體伺服器強化

圖 1.媒體伺服器強化的架構更改

這種新的架構確保即使進程受到損害,惡意程式碼也無法存取mediaserver先前持有的全套權限。進程受 SElinux 和 seccomp 策略的限制。

注意:由於供應商依賴性,某些編解碼器仍在mediaserver中運行,因此授予mediaserver超出必要的權限。具體來說,Widevine Classic 繼續在 Android 7.0 的mediaserver中運行。

媒體伺服器變更

在Android 7.0中, mediaserver進程用於驅動播放和錄製,例如在元件和進程之間傳遞和同步緩衝區。進程之間透過標準的Binder機制進行通訊。

在標準本機檔案播放會話中,應用程式將檔案描述符 (FD) 傳遞到mediaserver (通常透過 MediaPlayer Java API),並且mediaserver

  1. 將 FD 包裝到傳遞給提取器程序的 Binder DataSource 物件中,提取器程序使用它透過 Binder IPC 從檔案中讀取資料。 (mediaextractor 不會取得 FD,而是透過 Binder 回呼mediaserver來取得資料。)
  2. 檢查文件,為文件類型建立適當的提取器(例如 MP3Extractor 或 MPEG4Extractor),並將提取器的 Binder 介面返回到mediaserver進程。
  3. 對擷取器進行 Binder IPC 呼叫以確定檔案中的資料類型(例如 MP3 或 H.264 資料)。
  4. 呼叫mediacodec進程來建立所需類型的編解碼器;接收這些編解碼器的 Binder 介面。
  5. 重複Binder IPC呼叫擷取器讀取編碼樣本,使用Binder IPC將編碼資料傳送到mediacodec進程進行解碼,並接收解碼資料。

在某些用例中,不涉及編解碼器(例如卸載播放,其中編碼資料直接發送到輸出裝置),或者編解碼器可以直接呈現解碼資料而不是返回解碼資料的緩衝區(視訊播放)。

MediaCodecService 變更

編解碼器服務是編碼器和解碼器所在的地方。由於供應商依賴性,並非所有編解碼器都存在於編解碼器程序中。在安卓7.0中:

  • 非安全解碼器和軟體編碼器存在於編解碼器流程中。
  • 安全解碼器和硬體編碼器位於mediaserver中(未更改)。

應用程式(或mediaserver )會呼叫編解碼器程序來建立所需類型的編解碼器,然後呼叫該編解碼器傳入編碼資料並檢索解碼資料(用於解碼)或傳入解碼資料並檢索編碼數據(用於編碼) 。編解碼器之間的資料傳輸已經使用共享內存,因此該過程不變。

MediaDrm伺服器更改

DRM 伺服器在播放受 DRM 保護的內容(例如 Google Play 電影中的電影)時使用。它以安全的方式處理加密資料的解密,因此可以存取憑證和金鑰儲存以及其他敏感元件。由於供應商依賴性,DRM 流程尚未在所有情況下使用。

音訊伺服器的變化

AudioServer 進程可託管與音訊相關的元件,例如音訊輸入和輸出、確定音訊路由的策略管理器服務以及 FM 廣播服務。有關音訊變更和實施指南的詳細信息,請參閱實施音訊

相機伺服器變更

CameraServer控制攝影機,在錄製影片時使用,從攝影機取得視訊幀,然後將其傳遞給mediaserver進行進一步處理。有關 CameraServer 變更的詳細變更和實施指南,請參閱相機框架強化

Extractor服務變更

提取器服務託管提取器,即解析媒體框架支援的各種文件格式的元件。提取器服務是所有服務中權限最小的,它無法讀取 FD,因此它會呼叫 Binder 介面(由mediaserver for每個播放會話提供)來存取檔案。

應用程式(或mediaserver )呼叫提取器程序來取得IMediaExtractor ,呼叫該IMediaExtractor來取得檔案中包含的軌道的IMediaSources ,然後呼叫IMediaSources從中讀取資料。

為了在進程之間傳輸數據,應用程式(或mediaserver )將數據包含在reply-Parcel中作為Binder事務的一部分或使用共享記憶體:

  • 使用共享內存需要額外的 Binder 呼叫來釋放共享內存,但速度更快,並且對於大緩衝區使用更少的電量。
  • 使用in-Parcel需要額外的複製,但速度更快,並且對於小於 64KB 的緩衝區使用更少的電量。

執行

為了支援將MediaDrmMediaCrypto元件移至新的mediadrmserver進程中,供應商必須更改安全緩衝區的分配方法,以允許緩衝區在進程之間共用。

在先前的 Android 版本中,安全緩衝區是透過OMX::allocateBuffermediaserver中分配的,並在同一進程的解密過程中使用,如下所示:

圖 2. Android 6.0 及更低版本媒體伺服器中的緩衝區分配。

在 Android 7.0 中,緩衝區分配過程已更改為一種新機制,該機制提供靈活性,同時最大限度地減少對現有實現的影響。透過新mediadrmserver進程中的MediaDrmMediaCrypto堆疊,緩衝區的分配方式不同,供應商必須更新安全緩衝區句柄,以便當MediaCodecMediaCrypto上呼叫解密操作時可以跨綁定器傳輸它們。

圖 3. Android 7.0 及更高版本媒體伺服器中的緩衝區分配。

使用本機句柄

OMX::allocateBuffer必須傳回一個指向native_handle結構的指針,該結構包含檔案描述符 (FD) 和其他整數資料。 native_handle具有使用 FD 的所有優點,包括對序列化/反序列化的現有綁定器支持,同時為目前不使用 FD 的供應商提供更大的靈活性。

使用native_handle_create()來指派本機句柄。框架程式碼擁有分配的native_handle結構的所有權,並負責在最初分配native_handle的進程和反序列化它的進程中釋放資源。此框架使用native_handle_close()釋放本機句柄,然後使用native_handle_delete()釋放本機句柄,並使用Parcel::writeNativeHandle()/readNativeHandle()序列化/反序列化native_handle

使用 FD 表示安全緩衝區的 SoC 供應商可以用他們的 FD 填入native_handle中的 FD。不使用 FD 的供應商可以使用native_buffer中的附加欄位來表示安全緩衝區。

設定解密位置

供應商必須更新對native_handle進行操作的 OEMCrypto 解密方法,以執行使native_handle在新進程空間中可用所需的任何特定於供應商的操作(更改通常包括對 OEMCrypto 庫的更新)。

由於allocateBuffer是標準 OMX 操作,Android 7.0 包含一個新的 OMX 擴充 ( OMX.google.android.index.allocateNativeHandle ) 來查詢此支持,以及一個OMX_SetParameter調用,通知 OMX 實作應該使用本機句柄。