Init vendor

Proses init memiliki izin yang hampir tidak dibatasi dan menggunakan skrip input dari partisi sistem dan vendor untuk melakukan inisialisasi sistem selama proses booting. Akses ini menyebabkan celah besar dalam pemisahan sistem/vendor Treble, karena skrip vendor dapat menginstruksikan init untuk mengakses file, properti, dll. yang tidak merupakan bagian dari antarmuka biner aplikasi vendor sistem yang stabil (ABI).

Vendor init dirancang untuk menutup celah ini dengan menggunakan domain Linux dengan keamanan yang ditingkatkan (SELinux) vendor_init terpisah untuk menjalankan perintah yang ditemukan di /vendor dengan izin khusus vendor.

Mekanisme

Init vendor membuat fork subproses init lebih awal dalam proses booting dengan konteks SELinux u:r:vendor_init:s0. Konteks SELinux ini memiliki izin yang jauh lebih sedikit daripada konteks init default dan aksesnya terbatas pada file, properti, dll. yang khusus vendor atau bagian dari ABI vendor sistem yang stabil.

Init memeriksa setiap skrip yang dimuat untuk melihat apakah jalurnya dimulai dengan /vendor dan jika ya, beri tag dengan indikasi bahwa perintahnya harus dijalankan dalam konteks init vendor. Setiap init bawaan dianotasi dengan boolean yang menentukan apakah perintah harus dijalankan di subproses init vendor atau tidak:

  • Sebagian besar perintah yang mengakses sistem file dianotasi untuk dijalankan di subproses init vendor sehingga tunduk pada SEPolicy init vendor.
  • Sebagian besar perintah yang memengaruhi status init internal (misalnya, memulai dan menghentikan layanan) dijalankan dalam proses init normal. Perintah ini diberi tahu bahwa skrip vendor memanggilnya untuk melakukan penanganan izin non-SELinux-nya sendiri.

Loop pemrosesan utama init berisi pemeriksaan bahwa jika perintah dianotasi untuk dijalankan di subproses vendor dan berasal dari skrip vendor, perintah tersebut akan dikirim melalui komunikasi antarproses (IPC) ke subproses init vendor, yang menjalankan perintah dan mengirim hasilnya kembali ke init.

Menggunakan init vendor

Inisialisasi vendor diaktifkan secara default dan pembatasannya berlaku untuk semua skrip init yang ada di partisi /vendor. Init vendor harus transparan terhadap vendor yang skripnya sudah tidak mengakses hanya file, properti, dll. sistem.

Namun, jika perintah dalam skrip vendor tertentu melanggar batasan init vendor, perintah akan gagal. Perintah yang gagal memiliki baris di log kernel (terlihat dengan dmesg) dari init yang menunjukkan kegagalan. Audit SELinux menemani perintah yang gagal karena kebijakan SELinux. Contoh kegagalan termasuk audit SELinux:

type=1400 audit(1511821362.996:9): avc: denied { search } for pid=540 comm="init" name="nfc" dev="sda45" ino=1310721 scontext=u:r:vendor_init:s0 tcontext=u:object_r:nfc_data_file:s0 tclass=dir permissive=0
init: Command 'write /data/nfc/bad_file_access 1234' action=boot (/vendor/etc/init/hw/init.walleye.rc:422) took 2ms and failed: Unable to write to file '/data/nfc/bad_file_access': open() failed: Permission denied

Jika perintah gagal, ada dua opsi:

  • Jika perintah gagal karena batasan yang diinginkan (seperti jika perintah mengakses file atau properti sistem), perintah harus diimplementasikan ulang dengan cara yang kompatibel dengan Treble, hanya melalui antarmuka yang stabil. Aturan Neverallow mencegah penambahan izin untuk mengakses file sistem yang bukan bagian dari ABI vendor sistem yang stabil.
  • Jika label SELinux baru dan belum diberi izin di vendor_init.te sistem atau izin yang dikecualikan melalui aturan neverallow, label baru dapat diberi izin di vendor_init.te khusus perangkat.

Untuk perangkat yang diluncurkan sebelum Android 9, aturan Neverallows dapat diabaikan dengan menambahkan typeattribute data_between_core_and_vendor_violators ke file vendor_init.te khusus perangkat.

Lokasi kode

Sebagian besar logika untuk IPC init vendor ada di system/core/init/subcontext.cpp.

Tabel perintah berada di class BuiltinFunctionMap di system/core/init/builtins.cpp dan menyertakan anotasi yang menunjukkan apakah perintah harus dijalankan dalam subproses init vendor.

SEPolicy untuk init vendor dibagi di direktori pribadi (system/sepolicy/private/vendor_init.te) dan publik (system/sepolicy/public/vendor_init.te) di system/sepolicy.