Inisialisasi vendor

Proses init memiliki izin yang hampir tidak dibatasi dan menggunakan skrip input dari partisi sistem dan vendor untuk menginisialisasi 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 bukan merupakan bagian dari antarmuka biner aplikasi sistem-vendor (ABI) yang stabil.

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

Mekanisme

Vendor init membuat fork subproses init pada 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 khusus untuk vendor atau bagian dari ABI sistem-vendor yang stabil.

Init memeriksa setiap skrip yang dimuat untuk melihat apakah jalur skrip dimulai dengan /vendor. Jika ya, skrip akan ditandai dengan indikasi bahwa perintahnya harus dijalankan dalam konteks init vendor. Setiap init bawaan diberi anotasi dengan boolean yang menentukan apakah perintah harus dijalankan dalam subproses init vendor atau tidak:

  • Sebagian besar perintah yang mengakses sistem file diberi anotasi untuk dijalankan dalam subproses init vendor dan oleh karena itu 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 mengetahui bahwa skrip vendor memanggilnya untuk melakukan penanganan izin non-SELinux sendiri.

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

Menggunakan init vendor

Init vendor diaktifkan secara default dan batasannya berlaku untuk semua skrip init yang ada di partisi /vendor. Init vendor harus transparan bagi vendor yang skripnya tidak mengakses file, properti, dll. khusus sistem.

Namun, jika perintah dalam skrip vendor tertentu melanggar batasan init vendor, perintah akan gagal. Perintah yang gagal memiliki baris dalam log kernel (terlihat dengan dmesg) dari init yang menunjukkan kegagalan. Audit SELinux menyertai perintah yang gagal karena kebijakan SELinux. Contoh kegagalan yang mencakup 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 dimaksudkan (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 merupakan bagian dari ABI sistem-vendor yang stabil.
  • Jika label SELinux baru dan belum diberikan izin dalam vendor_init.te sistem maupun 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 jenis data_between_core_and_vendor_violators ke file vendor_init.te khusus perangkat.

Lokasi kode

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

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

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