Başlatma işlemi neredeyse sınırsız izinlere sahiptir ve başlatma işlemi sırasında sistemi başlatmak için hem sistem hem de satıcı bölümlerindeki giriş komut dosyalarını kullanır. Bu erişim, Treble sistem/sağlayıcı ayrımında büyük bir boşluğa neden olur. Çünkü sağlayıcı komut dosyaları, init'e kararlı sistem-sağlayıcı uygulama ikili arabiriminin (ABI) bir parçası olmayan dosyalara, özelliklere vb. erişme talimatı verebilir.
Vendor init, vendor_init
içinde bulunan komutları satıcıya özel izinlerle çalıştırmak için ayrı bir güvenlik açısından geliştirilmiş Linux (SELinux) alanı kullanarak bu açığı kapatmak üzere tasarlanmıştır./vendor
Mekanizma
Tedarikçi başlatma, başlatma sürecinin başlarında u:r:vendor_init:s0
SELinux bağlamıyla başlatma işleminin bir alt sürecini oluşturur. Bu SELinux bağlamı, varsayılan init bağlamına kıyasla çok daha az izne sahiptir ve erişimi, satıcıya özel olan veya kararlı sistem-satıcı ABI'sinin parçası olan dosyalar, özellikler vb. ile sınırlıdır.
Init, yüklediği her komut dosyasının yolunun /vendor
ile başlayıp başlamadığını kontrol eder. Başlıyorsa komutlarının satıcı init bağlamında çalıştırılması gerektiğini belirten bir etiketle işaretler. Her init yerleşiği, komutun satıcı init alt işleminde çalıştırılıp çalıştırılmayacağını belirten bir boole değeriyle açıklanır:
- Dosya sistemine erişen komutların çoğu, tedarikçi init alt sürecinde çalışacak şekilde açıklama eklenmiş olduğundan tedarikçi init SEPolicy'ye tabidir.
- Dahili başlatma durumunu etkileyen komutların çoğu (ör. hizmetleri başlatma ve durdurma) normal başlatma işlemi içinde çalıştırılır. Bu komutlar, bir satıcı komut dosyasının kendi SELinux dışı izin işleme işlemlerini yapması için kendilerini çağırdığının farkındadır.
init'in ana işleme döngüsü, bir komutun tedarikçi alt sürecinde çalışacak şekilde açıklama eklenmişse ve tedarikçi komut dosyasından geliyorsa bu komutun, süreçler arası iletişim (IPC) aracılığıyla tedarikçi init alt sürecine gönderilmesini sağlayan bir kontrol içerir. Bu alt süreç, komutu çalıştırır ve sonucu init'e geri gönderir.
Tedarikçi başlatma özelliğini kullanma
Tedarikçi başlatma varsayılan olarak etkindir ve kısıtlamaları, /vendor
bölümünde bulunan tüm başlatma komut dosyaları için geçerlidir. Tedarikçi başlatma, komut dosyaları zaten yalnızca sistem dosyalarına, özelliklere vb. erişmeyen tedarikçiler için şeffaf olmalıdır.
Ancak belirli bir tedarikçi komut dosyasındaki komutlar, tedarikçi başlatma kısıtlamalarını ihlal ederse komutlar başarısız olur. Başarısız olan komutlar, çekirdek günlüğünde (dmesg ile görünür) init'ten gelen ve hatayı gösteren bir satıra sahiptir. SELinux politikası nedeniyle başarısız olan tüm komutlara SELinux denetimi eşlik eder. SELinux denetimi içeren bir hataya örnek:
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
Bir komut başarısız olursa iki seçeneğiniz vardır:
- Komut, amaçlanan bir kısıtlama nedeniyle (ör. komut bir sistem dosyasına veya özelliğine erişiyorsa) başarısız oluyorsa yalnızca kararlı arayüzlerden geçerek Treble ile uyumlu bir şekilde yeniden uygulanmalıdır. Neverallow kuralları, kararlı sistem-satıcı ABI'sinin parçası olmayan sistem dosyalarına erişim izni eklenmesini engeller.
- SELinux etiketi yeni ve sistemde
vendor_init.te
izinleri verilmemişse veya neverallow kuralları aracılığıyla izinler hariç tutulmamışsa yeni etikete cihaza özelvendor_init.te
izinleri verilebilir.
Android 9'dan önce kullanıma sunulan cihazlarda, data_between_core_and_vendor_violators
typeattribute'ü cihaza özel vendor_init.te
dosyasına eklenerek neverallows kuralları atlanabilir.
Kod konumları
Tedarikçi başlatma IPC'siyle ilgili mantığın büyük bir kısmı system/core/init/subcontext.cpp dosyasında bulunur.
Komut tablosu, system/core/init/builtins.cpp dosyasındaki BuiltinFunctionMap
sınıfındadır ve komutun tedarikçi init alt işleminde çalıştırılması gerekip gerekmediğini belirten ek açıklamalar içerir.
Satıcı başlatma için SEPolicy, system/sepolicy dizinindeki özel (system/sepolicy/private/vendor_init.te) ve herkese açık (system/sepolicy/public/vendor_init.te) dizinlere ayrılmıştır.