Budowanie polityki SELinux

W tym artykule opisano, jak budowana jest polityka SELinux. Polityka SELinux jest zbudowana z połączenia podstawowej polityki AOSP (platforma) i polityki specyficznej dla urządzenia (dostawca). Proces tworzenia zasad SELinux dla Androida 4.4 do Androida 7.0 połączył wszystkie fragmenty sepolicy, a następnie wygenerował monolityczne pliki w katalogu głównym. Oznaczało to, że dostawcy SoC i producenci ODM modyfikowali boot.img (dla urządzeń innych niż A/B) lub system.img (dla urządzeń A/B) za każdym razem, gdy modyfikowano politykę.

W Androidzie 8.0 i nowszych zasady dotyczące platformy i dostawcy są tworzone osobno. SOC i producenci OEM mogą aktualizować swoje części zasad, tworzyć swoje obrazy (takie jak vendor.img i boot.img ), a następnie aktualizować te obrazy niezależnie od aktualizacji platformy.

Jednakże, ponieważ modułowe pliki zasad SELinux są przechowywane na partycjach /vendor , proces init musi wcześniej zamontować partycje systemowe i partycje dostawcy, aby mógł odczytać pliki SELinux z tych partycji i połączyć je z podstawowymi plikami SELinux w katalogu systemowym (przed załadowaniem ich do jądro).

Pliki źródłowe

Logika budowania SELinuksa znajduje się w tych plikach:

  • external/selinux : Zewnętrzny projekt SELinux, używany do budowania narzędzi wiersza poleceń HOST do kompilowania zasad i etykiet SELinux.
    • external/selinux/libselinux : Android używa tylko podzbioru zewnętrznego projektu libselinux wraz z pewnymi dostosowaniami specyficznymi dla Androida. Aby uzyskać szczegółowe informacje, zobacz external/selinux/README.android .
    • external/selinux/libsepol :
      • chkcon : Określ, czy kontekst zabezpieczeń jest prawidłowy dla danej polityki binarnej (plik wykonywalny hosta).
      • libsepol : biblioteka SELinux do manipulowania binarnymi politykami bezpieczeństwa (biblioteka statyczna/współdzielona hosta, docelowa biblioteka statyczna).
    • external/selinux/checkpolicy : Kompilator zasad SELinux (pliki wykonywalne hosta: checkpolicy , checkmodule i dispol ). Zależy od libsepol .
  • system/sepolicy : podstawowe konfiguracje zasad systemu Android SELinux, w tym konteksty i pliki zasad. Znajduje się tu także główna logika kompilacji sepolicy ( system/sepolicy/Android.mk ).

Więcej szczegółów na temat plików w system/sepolicy Implementing SELinux .

Android 7.0 i starsze

W tej sekcji opisano, jak zasady SELinux są zbudowane w systemie Android 7.x i wcześniejszych wersjach.

Budowanie polityki SELinux

Polityka SELinux jest tworzona poprzez połączenie podstawowej polityki AOSP z dostosowaniami specyficznymi dla urządzenia. Połączone zasady są następnie przekazywane do kompilatora zasad i różnych modułów sprawdzających. Dostosowanie specyficzne dla urządzenia odbywa się poprzez zmienną BOARD_SEPOLICY_DIRS zdefiniowaną w pliku Boardconfig.mk specyficznym dla urządzenia. Ta globalna zmienna kompilacji zawiera listę katalogów określających kolejność wyszukiwania dodatkowych plików strategii.

Na przykład sprzedawca SoC i ODM mogą dodać katalog, jeden dla ustawień specyficznych dla SoC, a drugi dla ustawień specyficznych dla urządzenia, aby wygenerować ostateczną konfigurację SELinux dla danego urządzenia:

  • BOARD_SEPOLICY_DIRS += device/ SOC /common/sepolicy
  • BOARD_SEPOLICY_DIRS += device/ SoC / DEVICE /sepolicy

Zawartość plików file_contexts w system/sepolicy i BOARD_SEPOLICY_DIRS jest łączona w celu wygenerowania pliku file_contexts.bin na urządzeniu:

Ten obraz przedstawia logikę kompilacji SELinux dla Androida 7.x.
Rysunek 1 . Logika kompilacji SELinux

Plik sepolicy składa się z wielu plików źródłowych:

  • Plik policy.conf w postaci zwykłego tekstu jest generowany przez połączenie security_classes , initial_sids , plików *.te , plików genfs_contexts i port_contexts w tej kolejności.
  • Dla każdego pliku (takiego jak security_classes ) jego zawartość jest konkatenacją plików o tej samej nazwie w katalogach system/sepolicy/ i BOARDS_SEPOLICY_DIRS .
  • Plik policy.conf jest wysyłany do kompilatora SELinux w celu sprawdzenia składni i kompilowany do formatu binarnego jako sepolicy na urządzeniu.
    Ten obraz przedstawia pliki generujące plik zasad SELinux dla Androida 7.x.
    Rysunek 2 . Plik zasad SELinux

Pliki SELinux

Po kompilacji urządzenia z Androidem w wersji 7.x i wcześniejszych zazwyczaj zawierają następujące pliki związane z SELinux:

  • selinux_version
  • sepolicy: wyjście binarne po połączeniu plików polityk (takich jak security_classes , initial_sids i *.te )
  • file_contexts
  • property_contexts
  • seapp_contexts
  • service_contexts
  • system/etc/mac_permissions.xml

Aby uzyskać więcej informacji, zobacz Implementowanie SELinux .

Inicjalizacja SELinuksa

Kiedy system się uruchamia, SELinux znajduje się w trybie zezwalającym (a nie w trybie wymuszającym). Proces inicjujący wykonuje następujące zadania:

  • Ładuje pliki sepolicy z ramdysku do jądra poprzez /sys/fs/selinux/load .
  • Przełącza SELinux w tryb wymuszania.
  • Uruchamia re-exec() , aby zastosować do siebie regułę domeny SELinux.

Aby skrócić czas uruchamiania, wykonaj re-exec() w procesie init tak szybko, jak to możliwe.

Android 8.0 i nowszy

W systemie Android 8.0 zasady SELinux są podzielone na komponenty platformy i dostawcy, aby umożliwić niezależne aktualizacje zasad platformy/dostawcy przy jednoczesnym zachowaniu zgodności.

Polityka platformy jest dalej podzielona na część prywatną platformy i część publiczną platformy w celu eksportowania określonych typów i atrybutów do autorów zasad dostawcy. Gwarantujemy, że publiczne typy/atrybuty platformy będą utrzymywane jako stabilne interfejsy API dla danej wersji platformy. Zgodność z publicznymi typami/atrybutami poprzedniej platformy można zagwarantować dla kilku wersji przy użyciu plików mapowania platformy.

Platforma publiczna polityka

Public sepolicy platformy obejmuje wszystko, co zdefiniowano w system/sepolicy/public . Platforma może przyjąć, że typy i atrybuty zdefiniowane w ramach polityki publicznej są stabilnymi API dla danej wersji platformy. Stanowi to część sepolicy eksportowaną przez platformę, na której twórcy zasad dostawcy (tj. urządzenia) mogą napisać dodatkowe zasady specyficzne dla urządzenia.

Wersjonowanie typów jest zgodne z wersją zasad, zgodnie z którą zapisywane są pliki dostawcy, zdefiniowaną przez zmienną kompilacji PLATFORM_SEPOLICY_VERSION . Wersjonowane zasady publiczne są następnie dołączane do zasad dostawcy i (w oryginalnej formie) do zasad platformy. Zatem ostateczna polityka obejmuje politykę platformy prywatnej, politykę publiczną bieżącej platformy, politykę dotyczącą konkretnego urządzenia oraz politykę publiczną z wersjami odpowiadającą wersji platformy, dla której napisano politykę dotyczącą urządzenia.

Polityka prywatności platformy

Prywatna sepolicy platformy obejmuje wszystko, co zdefiniowano w /system/sepolicy/private . Ta część zasad określa typy, uprawnienia i atrybuty wymagane tylko dla platformy. Nie są one eksportowane do twórców zasad vendor/device . Twórcom zasad niebędącym platformą nie wolno pisać rozszerzeń zasad w oparciu o typy/atrybuty/reguły zdefiniowane w prywatnej polityce platformy. Co więcej, zasady te można modyfikować lub mogą zniknąć w ramach aktualizacji obejmującej wyłącznie ramy.

Mapowanie prywatne platformy

Mapowanie prywatne platformy obejmuje instrukcje zasad, które odwzorowują atrybuty ujawnione w zasadach publicznych platformy poprzednich wersji platformy na konkretne typy używane w bieżącej polityce publicznej platformy. Dzięki temu zasady dostawcy, które zostały napisane w oparciu o publiczne atrybuty platformy z poprzednich wersji zasad publicznych platformy, będą nadal działać. Wersjonowanie opiera się na zmiennej kompilacji PLATFORM_SEPOLICY_VERSION ustawionej w AOSP dla danej wersji platformy. Dla każdej poprzedniej wersji platformy istnieje oddzielny plik mapowania, od którego oczekuje się, że platforma będzie akceptować zasady dostawcy. Aby uzyskać więcej informacji, zobacz Zgodność .

Android 11 i nowszy

system_ext i sepolicy produktu

W systemie Android 11 dodano politykę system_ext i politykę produktu. Podobnie jak sepolicy platformy, polityka system_ext i polityka produktu są podzielone na politykę publiczną i politykę prywatną.

Zasady publiczne są eksportowane do dostawcy. Typy i atrybuty stają się stabilnym interfejsem API, a zasady dostawcy mogą odnosić się do typów i atrybutów w zasadach publicznych. Wersjonowanie typów jest zgodne z PLATFORM_SEPOLICY_VERSION , a zasady wersjonowane są uwzględniane w zasadach dostawcy. Oryginalna polityka jest dołączona do każdej partycji system_ext i partycji produktu.

Polityka prywatna zawiera typy, uprawnienia i atrybuty wymagane tylko do rozszerzenia systemowego i produktu, wymagane do funkcjonalności partycji system_ext i produktów. Polityka prywatna jest niewidoczna dla dostawcy, co oznacza, że ​​zasady te mają charakter wewnętrzny i można je modyfikować.

system_ext i mapowanie produktu

system_ext i produkt mogą eksportować wyznaczone typy publiczne do dostawcy. Jednakże odpowiedzialność za utrzymanie kompatybilności spoczywa na każdym partnerze. W celu zapewnienia zgodności partnerzy mogą udostępnić własne pliki mapowania, które odwzorowują wersjonowane atrybuty poprzednich wersji na konkretne typy używane w bieżącej sepolicy publicznej.

  • Aby zainstalować plik mapowania dla system_ext, umieść plik cil zawierający żądane informacje o mapowaniu w {SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil , a następnie dodaj system_ext_{ver}.cil do PRODUCT_PACKAGES .
  • Aby zainstalować plik mapowania dla produktu, umieść plik cil zawierający żądane informacje o mapowaniu w {PRODUCT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil , a następnie dodaj product_{ver}.cil do PRODUCT_PACKAGES .
  • Zapoznaj się z przykładem , który dodaje plik mapowania partycji produktu urządzenia Redbull.

    Budowanie polityki SELinux

    Polityka SELinux w Androidzie 8.0 jest tworzona poprzez połączenie elementów z /system i /vendor . Logika dotycząca odpowiedniego ustawienia znajduje się w /platform/system/sepolicy/Android.mk .

    Polityka istnieje w następujących lokalizacjach:

    Lokalizacja Zawiera
    system/sepolicy/public sepolicy API platformy
    system/sepolicy/private Szczegóły implementacji platformy (dostawcy mogą zignorować)
    system/sepolicy/vendor Pliki zasad i kontekstu, z których mogą korzystać dostawcy (dostawcy mogą w razie potrzeby zignorować)
    BOARD_SEPOLICY_DIRS Polityka sprzedawcy
    BOARD_ODM_SEPOLICY_DIRS (Android 9 i nowsze) Dziwna polityka
    SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS (Android 11 i nowsze) Interfejs API sepolicy System_ext
    SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS (Android 11 i nowsze) Szczegóły implementacji System_ext (dostawcy mogą zignorować)
    PRODUCT_PUBLIC_SEPOLICY_DIRS (Android 11 i nowsze) API sepolicy produktu
    PRODUCT_PRIVATE_SEPOLICY_DIRS (Android 11 i nowsze) Szczegóły wdrożenia produktu (sprzedawcy mogą zignorować)

    System kompilacji przyjmuje tę politykę i tworzy komponenty polityki systemowej, system_ext, produktu, dostawcy i odm na odpowiedniej partycji. Kroki obejmują:

    1. Konwertowanie polityk do formatu SELinux Common Intermediate Language (CIL), w szczególności:
      1. Polityka platformy publicznej (system + system_ext + produkt)
      2. połączona polityka prywatna + publiczna
      3. polityka publiczna + dostawca i BOARD_SEPOLICY_DIRS
    2. Wersjonowanie zasad dostarczonych przez public w ramach zasad dostawcy. Dokonano tego za pomocą utworzonej publicznej polityki CIL w celu poinformowania połączonej polityki publicznej + dostawcy + BOARD_SEPOLICY_DIRS o tym, które części należy przekształcić w atrybuty, które zostaną powiązane z polityką platformy.
    3. Tworzenie pliku mapowania łączącego platformę i części dostawcy. Początkowo łączy to po prostu typy z polityki publicznej z odpowiednimi atrybutami w polityce dostawcy; później będzie również stanowić podstawę dla pliku utrzymywanego w przyszłych wersjach platformy, zapewniając zgodność z polityką dostawcy dotyczącą tej wersji platformy.
    4. Łączenie plików zasad (opisz zarówno rozwiązania na urządzeniu, jak i rozwiązania prekompilowane).
      1. Połącz zasady mapowania, platformy i dostawcy.
      2. Skompiluj wyjściowy plik zasad binarnych.

    Prekompilowana polityka SELinux

    Zanim init włączy SELinux, init zbiera wszystkie pliki CIL z partycji ( system , system_ext , product , vendor i odm ) i kompiluje je do polityki binarnej, formatu, który można załadować do jądra. Ponieważ kompilacja zajmuje trochę czasu (zwykle 1-2 sekundy), pliki CIL są wstępnie kompilowane w czasie kompilacji i umieszczane w katalogu /vendor/etc/selinux/precompiled_sepolicy lub /odm/etc/selinux/precompiled_sepolicy wraz z skrótami sha256 wejściowych plików CIL. W czasie wykonywania init sprawdza, czy którykolwiek plik strategii został zaktualizowany, porównując skróty. Jeśli nic się nie zmieniło, init ładuje prekompilowaną politykę. Jeśli nie, init kompiluje w locie i używa go zamiast prekompilowanego.

    Mówiąc dokładniej, zasady prekompilowane są używane, jeśli spełnione są wszystkie poniższe warunki. Tutaj {partition} reprezentuje partycję, na której istnieje prekompilowana polityka: vendor lub odm .

    • Zarówno /system/etc/selinux/plat_sepolicy_and_mapping.sha256 , jak i /{partition}/etc/selinux/precompiled_sepolicy.plat_sepolicy_and_mapping.sha256 istnieją i są identyczne.
    • Zarówno /system_ext/etc/selinux/system_ext_sepolicy_and_mapping.sha256 , jak i /{partition}/etc/selinux/precompiled_sepolicy.system_ext_sepolicy_and_mapping.sha256 nie istnieją. Albo oba istnieją i są identyczne.
    • Zarówno /product/etc/selinux/product_sepolicy_and_mapping.sha256 , jak i /{partition}/etc/selinux/precompiled_sepolicy.product_sepolicy_and_mapping.sha256 nie istnieją. Albo oba istnieją i są identyczne.

    Jeśli którykolwiek z nich się różni, init powraca do ścieżki kompilacji na urządzeniu. Więcej szczegółów znajdziesz w system/core/init/selinux.cpp .