Untuk meningkatkan keamanan perangkat, Android 7.0 memecah proses mediaserver
media monolitik menjadi beberapa proses dengan izin dan kemampuan yang dibatasi hanya yang diperlukan oleh setiap proses. Perubahan ini mengurangi kerentanan keamanan kerangka kerja 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 pengguna akhir dan data 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 mengasumsikan semuanya berjalan dalam proses yang sama, vendor harus memperbarui kode mereka untuk menyebarkan pegangan asli ( native_handle
) yang memiliki arti di seluruh proses. Untuk implementasi referensi perubahan yang terkait dengan pengerasan media, lihat frameworks/av
dan frameworks/native
.
Perubahan arsitektur
Versi Android sebelumnya menggunakan proses mediaserver
monolitik tunggal dengan banyak izin (akses kamera, akses audio, akses driver video, akses file, akses jaringan, dll.). Android 7.0 membagi proses mediaserver
media 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 set lengkap izin yang sebelumnya dipegang oleh server media. Proses dibatasi oleh SElinux dan kebijakan seccomp.
Catatan: Karena ketergantungan vendor, beberapa codec masih berjalan di mediaserver
media dan akibatnya memberikan mediaserver
lebih banyak kepada server media daripada yang diperlukan. Secara khusus, Widevine Classic terus berjalan di mediaserver
media untuk Android 7.0.
Perubahan MediaServer
Di Android 7.0, ada proses mediaserver
media 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
media (biasanya melalui MediaPlayer Java API), dan mediaserver
media :
- Membungkus FD menjadi objek Binder DataSource yang diteruskan ke proses ekstraktor, yang menggunakannya untuk membaca dari file menggunakan Binder IPC. (
mediaserver
tidak mendapatkan FD tetapi membuat panggilan Binder kembali ke server media untuk mendapatkan data.) - Memeriksa file, membuat ekstraktor yang sesuai untuk jenis file (misalnya MP3Extractor, atau
mediaserver
), dan mengembalikan antarmuka Binder untuk ekstraktor ke proses server media. - Membuat panggilan IPC Binder ke extractor untuk menentukan jenis data dalam file (misalnya data MP3 atau H.264).
- Panggilan ke dalam proses
mediacodec
untuk membuat codec dari jenis yang diperlukan; menerima antarmuka Binder untuk codec ini. - Membuat panggilan IPC Binder berulang ke ekstraktor untuk membaca sampel yang disandikan, menggunakan IPC Binder untuk mengirim data yang disandikan ke proses
mediacodec
untuk decoding, dan menerima data yang didekodekan.
Dalam beberapa kasus penggunaan, tidak ada codec yang terlibat (seperti pemutaran offloaded di mana data yang dikodekan dikirim langsung ke perangkat output), atau codec dapat membuat data yang didekodekan secara langsung alih-alih mengembalikan buffer data yang didekodekan (pemutaran video).
Perubahan Layanan MediaCodec
Layanan codec adalah tempat encoder dan decoder tinggal. Karena ketergantungan vendor, belum semua codec hidup 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 hidup di
mediaserver
media (tidak berubah).
Sebuah aplikasi (atau server media) memanggil proses codec untuk membuat codec dari jenis yang diperlukan, kemudian memanggil codec itu untuk meneruskan data yang disandikan dan mengambil data yang didekodekan (untuk decoding) atau untuk meneruskan data yang didekodekan dan mengambil data yang disandikan (untuk encoding) . 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 dan komponen sensitif lainnya. Karena ketergantungan vendor, proses DRM belum digunakan dalam semua kasus.
Perubahan AudioServer
Proses AudioServer menghosting komponen terkait audio seperti input dan output audio, layanan policymanager yang menentukan perutean audio, dan layanan radio FM. Untuk detail tentang perubahan Audio dan panduan penerapan, lihat Menerapkan Audio .
KameraServer berubah
mediaserver
mengontrol kamera dan digunakan saat merekam video untuk mendapatkan bingkai video dari kamera dan kemudian meneruskannya ke server media untuk penanganan lebih lanjut. Untuk detail tentang perubahan dan panduan implementasi untuk perubahan CameraServer, lihat Camera Framework Hardening .
Perubahan ExtractorService
Layanan ekstraktor menghosting ekstraktor , komponen yang mengurai berbagai format file yang didukung oleh kerangka kerja media. Layanan ekstraktor adalah yang paling tidak memiliki hak istimewa dari semua layanan—tidak dapat membaca FD jadi alih-alih membuat panggilan ke antarmuka Binder (disediakan oleh server media mediaserver for
setiap sesi pemutaran) untuk mengakses file.
Aplikasi (atau IMediaExtractor
mediaserver
memanggil IMediaExtractor
untuk mendapatkan IMediaSources
untuk trek yang terdapat dalam file, dan kemudian memanggil IMediaSources
untuk membaca data dari mereka.
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 tambahan 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 pemindahan komponen MediaDrm
dan MediaCrypto
ke dalam proses mediadrmserver
baru, vendor harus mengubah metode alokasi buffer aman untuk memungkinkan buffer dibagikan di antara proses.
Dalam 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 berubah menjadi mekanisme baru yang memberikan fleksibilitas sekaligus meminimalkan dampak pada implementasi yang ada. Dengan tumpukan MediaDrm
dan MediaCrypto
dalam proses mediadrmserver
yang baru, buffer dialokasikan secara berbeda dan vendor harus memperbarui pegangan buffer yang aman sehingga dapat diangkut melintasi pengikat saat MediaCodec
menjalankan operasi dekripsi pada MediaCrypto
.
Menggunakan 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, sementara memungkinkan lebih banyak fleksibilitas untuk 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 deserialized. Kerangka kerja melepaskan 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 bidang tambahan di native_buffer
.
Mengatur lokasi dekripsi
Vendor harus memperbarui metode dekripsi OEMCrypto yang beroperasi pada native_handle
untuk melakukan operasi khusus vendor yang diperlukan agar native_handle
dapat digunakan di ruang proses baru (perubahan biasanya mencakup pembaruan ke pustaka OEMCrypto).
Karena allocateBuffer
adalah operasi OMX standar, Android 7.0 menyertakan ekstensi OMX baru ( OMX.google.android.index.allocateNativeHandle
) untuk meminta dukungan ini dan panggilan OMX_SetParameter
yang memberi tahu implementasi OMX bahwa itu harus menggunakan pegangan asli.