Untuk meningkatkan keamanan perangkat, Android 7.0 memecah proses mediaserver
monolitik menjadi beberapa proses dengan izin dan kemampuan terbatas hanya pada proses yang diperlukan oleh setiap proses. Perubahan ini memitigasi kerentanan keamanan kerangka media dengan:
- Memisahkan komponen pipeline AV ke dalam proses sandbox khusus aplikasi.
- Mengaktifkan komponen media yang dapat diperbarui (ekstraktor, codec, dll.).
Perubahan ini juga meningkatkan keamanan bagi pengguna akhir dengan secara signifikan mengurangi tingkat keparahan sebagian besar kerentanan keamanan terkait media, menjaga perangkat dan data pengguna akhir tetap aman.
Vendor OEM dan SoC perlu memperbarui HAL dan perubahan kerangka kerja mereka agar kompatibel dengan arsitektur baru. Khususnya, karena kode Android yang disediakan vendor sering kali mengasumsikan segala sesuatunya berjalan dalam proses yang sama, vendor harus memperbarui kode mereka untuk meneruskan handle asli ( native_handle
) yang memiliki arti di seluruh proses. Untuk referensi penerapan perubahan terkait pengerasan media, lihat frameworks/av
dan frameworks/native
.
Perubahan arsitektur
Versi Android sebelumnya menggunakan satu proses mediaserver
monolitik dengan banyak izin (akses kamera, akses audio, akses driver video, akses file, akses jaringan, dll.). Android 7.0 membagi proses mediaserver
menjadi beberapa proses baru yang masing-masing memerlukan serangkaian izin yang jauh lebih kecil:
Arsitektur baru ini memastikan bahwa meskipun suatu proses disusupi, kode berbahaya tidak memiliki akses ke seluruh izin yang sebelumnya dimiliki oleh mediaserver
. Proses dibatasi oleh kebijakan SElinux dan seccomp.
Catatan: Karena ketergantungan vendor, beberapa codec masih berjalan di mediaserver
dan akibatnya memberikan izin mediaserver
lebih dari yang diperlukan. Secara khusus, Widevine Classic terus berjalan di mediaserver
untuk Android 7.0.
Perubahan Server Media
Di Android 7.0, ada proses mediaserver
untuk mendorong pemutaran dan perekaman, misalnya meneruskan dan menyinkronkan buffer antara komponen dan proses. Proses berkomunikasi melalui mekanisme Binder standar.
Dalam sesi pemutaran file lokal standar, aplikasi meneruskan deskriptor file (FD) ke mediaserver
(biasanya melalui MediaPlayer Java API), dan mediaserver
:
- Membungkus FD menjadi objek Binder DataSource yang diteruskan ke proses ekstraktor, yang menggunakannya untuk membaca dari file menggunakan Binder IPC. (Mediaextractor tidak mendapatkan FD melainkan membuat Binder memanggil kembali ke
mediaserver
untuk mendapatkan data.) - Memeriksa file, membuat ekstraktor yang sesuai untuk jenis file (misalnya MP3Extractor, atau MPEG4Extractor), dan mengembalikan antarmuka Binder untuk ekstraktor ke proses
mediaserver
. - Melakukan panggilan Binder IPC ke ekstraktor untuk menentukan jenis data dalam file (misalnya data MP3 atau H.264).
- Memanggil proses
mediacodec
untuk membuat codec dari jenis yang diperlukan; menerima antarmuka Binder untuk codec ini. - Melakukan panggilan Binder IPC berulang kali ke ekstraktor untuk membaca sampel yang dikodekan, menggunakan Binder IPC untuk mengirim data yang dikodekan ke proses
mediacodec
untuk didekode, dan menerima data yang didekodekan.
Dalam beberapa kasus penggunaan, tidak ada codec yang terlibat (seperti pemutaran yang dibongkar di mana data yang dikodekan dikirim langsung ke perangkat keluaran), atau codec dapat merender data yang didekode secara langsung alih-alih mengembalikan buffer data yang didekode (pemutaran video).
Perubahan MediaCodecService
Layanan codec adalah tempat encoder dan decoder berada. Karena ketergantungan vendor, belum semua codec aktif dalam proses codec. Di Android 7.0:
- Decoder dan encoder perangkat lunak yang tidak aman hidup dalam proses codec.
- Decoder aman dan encoder perangkat keras berada di
mediaserver
(tidak berubah).
Sebuah aplikasi (atau mediaserver
) memanggil proses codec untuk membuat codec dari jenis yang diperlukan, kemudian memanggil codec tersebut untuk meneruskan data yang dikodekan dan mengambil data yang didekodekan (untuk decoding) atau untuk meneruskan data yang didekodekan dan mengambil data yang dikodekan (untuk pengkodean) . Transfer data ke dan dari codec sudah menggunakan memori bersama, sehingga prosesnya tidak berubah.
Perubahan MediaDrmServer
Server DRM digunakan saat memutar konten yang dilindungi DRM, seperti film di Google Play Film. Ini menangani dekripsi data terenkripsi dengan cara yang aman, dan dengan demikian memiliki akses ke sertifikat dan penyimpanan kunci serta komponen sensitif lainnya. Karena ketergantungan vendor, proses DRM belum digunakan di semua kasus.
Perubahan AudioServer
Proses AudioServer menghosting komponen terkait audio seperti input dan output audio, layanan manajer kebijakan yang menentukan perutean audio, dan layanan radio FM. Untuk detail tentang perubahan Audio dan panduan penerapan, lihat Menerapkan audio .
Perubahan Server Kamera
CameraServer mengontrol kamera dan digunakan saat merekam video untuk mendapatkan frame video dari kamera dan kemudian meneruskannya ke mediaserver
untuk penanganan lebih lanjut. Untuk detail tentang perubahan dan panduan penerapan perubahan CameraServer, lihat Pengerasan Kerangka Kamera .
Perubahan ExtractorService
Layanan ekstraktor menampung ekstraktor , komponen yang mengurai berbagai format file yang didukung oleh kerangka media. Layanan ekstraktor adalah layanan yang paling tidak memiliki hak istimewa—layanan ini tidak dapat membaca FD sehingga layanan ini melakukan panggilan ke antarmuka Binder (yang disediakan oleh mediaserver for
setiap sesi pemutaran) untuk mengakses file.
Sebuah aplikasi (atau mediaserver
) melakukan panggilan ke proses ekstraktor untuk mendapatkan IMediaExtractor
, memanggil IMediaExtractor
tersebut untuk mendapatkan IMediaSources
untuk trek yang terdapat dalam file, dan kemudian memanggil IMediaSources
untuk membaca data darinya.
Untuk mentransfer data antar proses, aplikasi (atau mediaserver
) menyertakan data dalam paket balasan sebagai bagian dari transaksi Binder atau menggunakan memori bersama:
- Menggunakan memori bersama memerlukan panggilan Binder ekstra untuk melepaskan memori bersama tetapi lebih cepat dan menggunakan lebih sedikit daya untuk buffer besar.
- Menggunakan in-Parcel memerlukan penyalinan ekstra tetapi lebih cepat dan menggunakan lebih sedikit daya untuk buffer yang lebih kecil dari 64KB.
Penerapan
Untuk mendukung perpindahan komponen MediaDrm
dan MediaCrypto
ke dalam proses mediadrmserver
baru, vendor harus mengubah metode alokasi buffer aman agar buffer dapat dibagikan antar proses.
Pada rilis Android sebelumnya, buffer aman dialokasikan di mediaserver
oleh OMX::allocateBuffer
dan digunakan selama dekripsi dalam proses yang sama, seperti yang ditunjukkan di bawah ini:
Di Android 7.0, proses alokasi buffer telah diubah menjadi mekanisme baru yang memberikan fleksibilitas sekaligus meminimalkan dampak pada implementasi yang sudah ada. Dengan tumpukan MediaDrm
dan MediaCrypto
dalam proses mediadrmserver
yang baru, buffer dialokasikan secara berbeda dan vendor harus memperbarui pegangan buffer aman sehingga buffer tersebut dapat dipindahkan melintasi binder ketika MediaCodec
menjalankan operasi dekripsi di MediaCrypto
.
Gunakan pegangan asli
OMX::allocateBuffer
harus mengembalikan pointer ke struct native_handle
, yang berisi deskriptor file (FD) dan data integer tambahan. native_handle
memiliki semua keuntungan menggunakan FD, termasuk dukungan pengikat yang ada untuk serialisasi/deserialisasi, sekaligus memberikan lebih banyak fleksibilitas bagi vendor yang saat ini tidak menggunakan FD.
Gunakan native_handle_create()
untuk mengalokasikan pegangan asli. Kode kerangka mengambil kepemilikan struct native_handle
yang dialokasikan dan bertanggung jawab untuk melepaskan sumber daya baik dalam proses di mana native_handle
awalnya dialokasikan dan dalam proses di mana ia dideserialisasi. Kerangka kerja ini merilis pegangan asli dengan native_handle_close()
diikuti oleh native_handle_delete()
dan membuat serial/deserialisasi native_handle
menggunakan Parcel::writeNativeHandle()/readNativeHandle()
.
Vendor SoC yang menggunakan FD untuk mewakili buffer aman dapat mengisi FD di native_handle
dengan FD mereka. Vendor yang tidak menggunakan FD dapat mewakili buffer aman menggunakan kolom tambahan di native_buffer
.
Tetapkan lokasi dekripsi
Vendor harus memperbarui metode dekripsi OEMCrypto yang beroperasi pada native_handle
untuk melakukan operasi spesifik vendor apa pun yang diperlukan agar native_handle
dapat digunakan di ruang proses baru (perubahan biasanya mencakup pembaruan pada perpustakaan OEMCrypto).
Karena allocateBuffer
adalah operasi OMX standar, Android 7.0 menyertakan ekstensi OMX baru ( OMX.google.android.index.allocateNativeHandle
) untuk menanyakan dukungan ini dan panggilan OMX_SetParameter
yang memberi tahu implementasi OMX bahwa ia harus menggunakan pengendali asli.