Inicjatywa dostawcy

Proces inicjowania ma prawie nieograniczone uprawnienia i wykorzystuje skrypty wejściowe z partycji systemowej i dostawcy do inicjowania systemu podczas procesu rozruchu. Dostęp ten powoduje ogromną lukę w podziale systemu Treble na dostawcę, ponieważ skrypty dostawców mogą instruować program init w celu uzyskania dostępu do plików, właściwości itp., które nie stanowią części stabilnego interfejsu binarnego aplikacji dostawcy systemu (ABI).

Vendor init ma na celu zamknięcie tej luki poprzez użycie oddzielnej domeny Linux (SELinux) o zwiększonym bezpieczeństwie, vendor_init do uruchamiania poleceń znalezionych w /vendor z uprawnieniami specyficznymi dla dostawcy.

Mechanizm

Vendor init rozwidla podproces init na początku procesu uruchamiania z kontekstem SELinux u:r:vendor_init:s0 . Ten kontekst SELinux ma znacznie mniej uprawnień niż domyślny kontekst init, a jego dostęp jest ograniczony do plików, właściwości itp., które są albo specyficzne dla dostawcy, albo stanowią część stabilnego ABI dostawcy systemu.

Init sprawdza każdy ładowany skrypt, aby zobaczyć, czy jego ścieżka zaczyna się od /vendor , a jeśli tak, oznacza go znacznikiem wskazującym, że jego polecenia muszą zostać uruchomione w kontekście inicjalizacji dostawcy. Każda funkcja wbudowana init jest opatrzona adnotacją wartości logicznej określającej, czy polecenie musi zostać uruchomione w podprocesie init dostawcy:

  • Większość poleceń uzyskujących dostęp do systemu plików ma adnotację, że należy je uruchamiać w podprocesie inicjowania dostawcy i dlatego podlega SEPolicy dostawcy init.
  • Większość poleceń mających wpływ na wewnętrzny stan inicjowania (np. uruchamianie i zatrzymywanie usług) jest uruchamianych w ramach normalnego procesu inicjowania. Polecenia te są informowane, że skrypt dostawcy wzywa je do wykonania własnej obsługi uprawnień innych niż SELinux.

Główna pętla przetwarzania init zawiera sprawdzenie, czy jeśli polecenie ma adnotację o uruchomieniu w podprocesie dostawcy i pochodzi ze skryptu dostawcy, to polecenie jest wysyłane za pośrednictwem komunikacji między procesami (IPC) do podprocesu inicjowania dostawcy, który uruchamia polecenie i wysyła wynik z powrotem do init.

Korzystanie z narzędzia Vendor Init

Funkcja Vendor init jest domyślnie włączona, a jej ograniczenia dotyczą wszystkich skryptów init znajdujących się na partycji /vendor . Inicjacja dostawcy powinna być przejrzysta dla dostawców, których skrypty nie uzyskują już dostępu wyłącznie do plików systemowych, właściwości itp.

Jeśli jednak polecenia w danym skrypcie dostawcy naruszają ograniczenia dotyczące inicjalizacji dostawcy, wykonanie tych poleceń zakończy się niepowodzeniem. Polecenia, które zakończyły się niepowodzeniem, mają w dzienniku jądra wiersz (widoczny za pomocą dmesg) z init wskazujący błąd. Audyt SELinux towarzyszy każdemu niepowołanemu poleceniu, które nie powiodło się z powodu polityki SELinux. Przykład niepowodzenia obejmującego audyt 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

Jeśli wykonanie polecenia nie powiedzie się, istnieją dwie możliwości:

  • Jeśli polecenie nie powiedzie się z powodu zamierzonych ograniczeń (takich jak polecenie uzyskuje dostęp do pliku systemowego lub właściwości), polecenie musi zostać ponownie zaimplementowane w sposób przyjazny dla Treble, przechodząc wyłącznie przez stabilne interfejsy. Reguły Neverallow uniemożliwiają dodawanie uprawnień dostępu do plików systemowych, które nie są częścią stabilnego ABI dostawcy systemu.
  • Jeśli etykieta SELinux jest nowa i nie ma jeszcze przyznanych uprawnień w systemie vendor_init.te ani wykluczonych uprawnień poprzez reguły Neverallow, nowa etykieta może otrzymać uprawnienia w specyficznym dla urządzenia vendor_init.te .

W przypadku urządzeń uruchamianych przed systemem Android 9 reguły Neverallows można ominąć, dodając atrybut data_between_core_and_vendor_violators do specyficznego dla urządzenia pliku vendor_init.te .

Lokalizacje kodu

Większość logiki dla init dostawcy IPC znajduje się w system/core/init/subcontext.cpp .

Tabela poleceń znajduje się w klasie BuiltinFunctionMap w pliku system/core/init/builtins.cpp i zawiera adnotacje wskazujące, czy polecenie musi zostać uruchomione w podprocesie inicjowania dostawcy.

SEPolicy dla dostawcy init jest podzielona na katalogi prywatny ( system/sepolicy/private/vendor_init.te ) i publiczny ( system/sepolicy/public/vendor_init.te ) w systemie/sepolicy.