Vendor Init

Proses init memiliki izin yang hampir tidak terbatas dan menggunakan skrip masukan dari partisi sistem dan vendor untuk menginisialisasi sistem selama proses boot. Akses ini menyebabkan lubang 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 (ABI) yang stabil.

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

Mekanisme

Vendor init melakukan fork pada subproses init di awal 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 spesifik untuk vendor atau bagian dari ABI vendor sistem yang stabil.

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

  • Sebagian besar perintah yang mengakses sistem file dianotasi untuk dijalankan di subproses vendor init dan oleh karena itu tunduk pada SEPolicy vendor init.
  • Kebanyakan perintah yang mempengaruhi keadaan init internal (misalnya, memulai dan menghentikan layanan) dijalankan dalam proses init normal. Perintah ini disadarkan bahwa skrip vendor memanggil mereka untuk melakukan penanganan izin non-SELinux sendiri.

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

Menggunakan Vendor Init

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

Namun, jika perintah dalam skrip vendor tertentu melanggar batasan vendor init, perintah tersebut akan gagal. Perintah yang gagal memiliki baris di log kernel (terlihat dengan dmesg) dari init yang menunjukkan kegagalan. Audit SELinux menyertai setiap 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 suatu perintah gagal, ada dua opsi:

  • Jika perintah gagal karena pembatasan yang dimaksudkan (seperti jika perintah mengakses file atau properti sistem), perintah harus diimplementasikan kembali dengan cara yang ramah 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 masih baru dan belum diberikan izin dalam sistem vendor_init.te atau izin yang dikecualikan melalui aturan neverallow, label baru dapat diberikan izin dalam vendor_init.te khusus perangkat.

Untuk perangkat yang diluncurkan sebelum Android 9, aturan neverallows dapat dilewati dengan menambahkan atribut type data_between_core_and_vendor_violators ke file vendor_init.te khusus perangkat.

Lokasi Kode

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

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

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