Google si impegna a promuovere l'equità razziale per le comunità nere. Vedi come.
Questa pagina è stata tradotta dall'API Cloud Translation.
Switch to English

Indurimento del framework dei media

Per migliorare la sicurezza dei dispositivi, Android 7.0 suddivide il processo monolitico del mediaserver in più processi con autorizzazioni e funzionalità limitate a quelle richieste da ciascun processo. Queste modifiche mitigano le vulnerabilità della sicurezza del framework dei media:

  • Suddivisione dei componenti della pipeline AV in processi sandbox specifici per app.
  • Abilitazione di componenti multimediali aggiornabili (estrattori, codec, ecc.).

Queste modifiche migliorano anche la sicurezza per gli utenti finali riducendo in modo significativo la gravità della maggior parte delle vulnerabilità di sicurezza relative ai media, mantenendo al sicuro i dispositivi e i dati degli utenti finali.

Gli OEM e i fornitori di SoC devono aggiornare le modifiche HAL e del framework per renderli compatibili con la nuova architettura. In particolare, poiché il codice Android fornito dal fornitore presuppone spesso che tutto funzioni nello stesso processo, i fornitori devono aggiornare il proprio codice per passare attraverso handle nativi ( native_handle ) che hanno significato tra i processi. Per un'implementazione di riferimento delle modifiche relative alla protezione dei media, fare riferimento a frameworks/av e frameworks/native .

Modifiche architettoniche

Le versioni precedenti di Android utilizzavano un singolo processo mediaserver monolitico con molte autorizzazioni (accesso alla telecamera, accesso audio, accesso al driver video, accesso ai file, accesso alla rete, ecc.). Android 7.0 suddivide il processo mediaserver in diversi nuovi processi che richiedono ciascuno un set di autorizzazioni molto più piccolo:

indurimento mediaserver

Figura 1. Modifiche all'architettura per l'indurimento del mediaserver

Questa nuova architettura garantisce che anche se un processo è compromesso, il codice dannoso non ha accesso al set completo di autorizzazioni precedentemente detenute da mediaserver. I processi sono limitati dalle politiche di SElinux e seccomp.

Nota: a causa delle dipendenze del fornitore, alcuni codec sono ancora in esecuzione nel mediaserver e di conseguenza concedono al mediaserver più autorizzazioni del necessario. In particolare, Widevine Classic continua a essere eseguito nel mediaserver per Android 7.0.

MediaServer cambia

In Android 7.0, il processo mediaserver esiste per guidare la riproduzione e la registrazione, ad esempio passando e sincronizzando i buffer tra componenti e processi. I processi comunicano attraverso il meccanismo Binder standard.

In una sessione di riproduzione di file locale standard, l'applicazione passa un descrittore di file (FD) al mediaserver (di solito tramite l'API Java di MediaPlayer) e il mediaserver :

  1. Avvolge l'FD in un oggetto Binder DataSource che viene passato al processo di estrazione, che lo utilizza per leggere dal file utilizzando Binder IPC. (Il mediaextractor non ottiene l'FD ma effettua invece le chiamate di Binder al mediaserver per ottenere i dati.)
  2. Esamina il file, crea l'estrattore appropriato per il tipo di file (ad esempio MP3Extractor o MPEG4Extractor) e restituisce un'interfaccia Binder per l'estrattore al processo mediaserver .
  3. Esegue chiamate IPC di Binder all'estrattore per determinare il tipo di dati nel file (ad es. Dati MP3 o H.264).
  4. Richiama il processo mediacodec per creare codec del tipo richiesto; riceve interfacce Binder per questi codec.
  5. Effettua ripetute chiamate IPC di Binder all'estrattore per leggere campioni codificati, utilizza Binder IPC per inviare dati codificati al processo mediacodec per la decodifica e riceve dati decodificati.

In alcuni casi d'uso, non è coinvolto nessun codec (come una riproduzione scaricata in cui i dati codificati vengono inviati direttamente al dispositivo di output), oppure il codec può eseguire il rendering dei dati decodificati direttamente invece di restituire un buffer di dati decodificati (riproduzione video).

Modifiche MediaCodecService

Il servizio di codec è dove vivono codificatori e decodificatori. A causa delle dipendenze dei fornitori, non tutti i codec vivono ancora nel processo di codec. In Android 7.0:

  • Decodificatori e codificatori software non sicuri vivono nel processo di codec.
  • Decodificatori sicuri e codificatori hardware vivono nel mediaserver (invariato).

Un'applicazione (o mediaserver) chiama il processo di codec per creare un codec del tipo richiesto, quindi chiama quel codec per trasmettere dati codificati e recuperare dati decodificati (per la decodifica) o per passare dati decodificati e recuperare dati codificati (per codifica) . Il trasferimento di dati da e verso i codec utilizza già la memoria condivisa, pertanto il processo rimane invariato.

MediaDrmServer cambia

Il server DRM viene utilizzato durante la riproduzione di contenuti protetti con DRM, come i film in Google Play Movies. Gestisce la decrittografia dei dati crittografati in modo sicuro e come tale ha accesso all'archivio certificati e chiavi e ad altri componenti sensibili. A causa delle dipendenze del fornitore, il processo DRM non è ancora utilizzato in tutti i casi.

AudioServer cambia

Il processo AudioServer ospita componenti audio correlati come input e output audio, il servizio policymanager che determina il routing audio e il servizio radio FM. Per i dettagli sulle modifiche dell'audio e la guida all'implementazione, consultare Implementazione dell'audio .

Cambiamenti di CameraServer

CameraServer controlla la telecamera e viene utilizzata durante la registrazione di video per ottenere fotogrammi video dalla telecamera e quindi passarli al mediaserver per un'ulteriore gestione. Per i dettagli sulle modifiche e la guida all'implementazione per le modifiche di CameraServer, consultare Indurimento di Camera Framework .

ExtractorService modifiche

Il servizio di estrazione ospita gli estrattori , componenti che analizzano i vari formati di file supportati dal framework dei media. Il servizio di estrazione è il meno privilegiato di tutti i servizi: non è in grado di leggere FD, quindi effettua chiamate su un'interfaccia Binder (fornita dal mediaserver for ogni sessione di riproduzione) per accedere ai file.

Un'applicazione (o mediaserver ) effettua una chiamata al processo di estrazione per ottenere un IMediaExtractor , chiama tale IMediaExtractor per ottenere IMediaSources per la traccia contenuta nel file, quindi chiama IMediaSources per leggere i dati da essi.

Per trasferire i dati tra processi, l'applicazione (o il mediaserver ) include i dati nel pacchetto di risposta come parte della transazione Binder o utilizza la memoria condivisa:

  • L'uso della memoria condivisa richiede una chiamata Binder aggiuntiva per rilasciare la memoria condivisa ma è più veloce e consuma meno energia per buffer di grandi dimensioni.
  • L'uso di in-Parcel richiede una copia extra ma è più veloce e consuma meno energia per buffer di dimensioni inferiori a 64 KB.

Implementazione

Per supportare lo spostamento dei componenti MediaDrm e MediaCrypto nel nuovo processo mediadrmserver , i fornitori devono modificare il metodo di allocazione per i buffer sicuri per consentire la condivisione dei buffer tra i processi.

Nelle versioni precedenti di Android, i buffer sicuri sono allocati in mediaserver da OMX::allocateBuffer e utilizzati durante la decodifica nello stesso processo, come mostrato di seguito:

Figura 2. Android 6.0 e allocazione del buffer inferiore nel mediaserver.

In Android 7.0, il processo di allocazione del buffer è stato modificato in un nuovo meccanismo che offre flessibilità minimizzando l'impatto sulle implementazioni esistenti. Con MediaDrm stack MediaDrm e MediaCrypto nel nuovo processo mediadrmserver , i buffer sono allocati in modo diverso e i fornitori devono aggiornare gli handle di buffer sicuri in modo che possano essere trasportati attraverso il raccoglitore quando MediaCodec invoca un'operazione di decrittografia su MediaCrypto .

Figura 3. Allocazione del buffer Android 7.0 e superiore in mediaserver.

Utilizzo di handle nativi

OMX::allocateBuffer deve restituire un puntatore a una struttura native_handle , che contiene descrittori di file (FD) e dati interi aggiuntivi. Un native_handle presenta tutti i vantaggi dell'utilizzo degli FD, incluso il supporto del raccoglitore esistente per la serializzazione / deserializzazione, consentendo al contempo una maggiore flessibilità per i fornitori che attualmente non utilizzano gli FD.

Utilizzare native_handle_create() per allocare l'handle nativo. Il codice framework prende la proprietà della struttura native_handle allocata ed è responsabile del rilascio delle risorse sia nel processo in cui è originariamente allocata la pagina native_handle sia nel processo in cui è deserializzato. Il framework rilascia handle nativi con native_handle_close() seguito da native_handle_delete() e serializza / deserializza native_handle usando Parcel::writeNativeHandle()/readNativeHandle() .

I fornitori di SoC che utilizzano FD per rappresentare buffer sicuri possono popolare l'FD in native_handle con il proprio FD. I fornitori che non utilizzano FD possono rappresentare buffer sicuri utilizzando campi aggiuntivi in native_buffer .

Impostazione della posizione di decodifica

I fornitori devono aggiornare il metodo di decrittografia OEMCrypto che opera su native_handle per eseguire tutte le operazioni specifiche del fornitore necessarie per rendere utilizzabile native_handle nel nuovo spazio del processo (le modifiche in genere includono aggiornamenti alle librerie OEMCrypto).

Poiché allocateBuffer è un'operazione OMX standard, Android 7.0 include una nuova estensione OMX ( OMX.google.android.index.allocateNativeHandle ) per eseguire una query per questo supporto e una chiamata OMX_SetParameter che notifica l'implementazione OMX che dovrebbe utilizzare handle nativi.