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 dotyczącej konkretnego urządzenia (dostawca). Przepływ kompilacji zasad SELinux dla Androida 4.4 do Androida 7.0 połączył wszystkie fragmenty sepolicy, a następnie wygenerował pliki monolityczne 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 systemie Android 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.

Ponieważ jednak zmodularyzowane pliki strategii 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 SELinux znajduje się w tych plikach:

  • external/selinux : Zewnętrzny projekt SELinux, używany do budowania narzędzi wiersza poleceń HOST do kompilowania polityki i etykiet SELinux.
    • external/selinux/libselinux : Android używa tylko podzbioru zewnętrznego projektu libselinux wraz z niektórymi dostosowaniami specyficznymi dla systemu Android. Aby uzyskać szczegółowe informacje, zobacz external/selinux/README.android .
    • external/selinux/libsepol :
      • chkcon : określa, czy kontekst zabezpieczeń jest prawidłowy dla danej zasady binarnej (plik wykonywalny hosta).
      • libsepol : biblioteka SELinux do manipulowania binarnymi politykami bezpieczeństwa (statyczna/współdzielona biblioteka hosta, docelowa biblioteka statyczna).
    • external/selinux/checkpolicy : kompilator strategii 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. Główna logika kompilacji sepolicy jest również tutaj ( system/sepolicy/Android.mk ).

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

Android 7.0 i starszy

W tej sekcji opisano, w jaki sposób zasady SELinux są budowane w systemie Android 7.x i wcześniejszych.

Polityka budowania SELinux

Polityka SELinux jest tworzona przez połączenie podstawowej polityki AOSP z dostosowaniami specyficznymi dla urządzenia. Połączona polityka jest następnie przekazywana do kompilatora polityk i różnych programów sprawdzających. Dostosowanie specyficzne dla urządzenia odbywa się za pomocą zmiennej BOARD_SEPOLICY_DIRS zdefiniowanej w pliku Boardconfig.mk specyficznego dla urządzenia. Ta globalna zmienna kompilacji zawiera listę katalogów, które określają kolejność wyszukiwania dodatkowych plików strategii.

Na przykład dostawca SoC i ODM mogą dodać katalog, jeden dla ustawień specyficznych dla SoC, a drugi dla ustawień specyficznych dla urządzenia, aby wygenerować ostateczne konfiguracje 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 file_contexts.bin na urządzeniu:

Ten obraz przedstawia logikę kompilacji SELinux dla systemu Android 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 łączenie w tej kolejności klas security_classes , initial_sids , *.te , genfs_contexts i port_contexts .
  • Dla każdego pliku (takiego jak security_classes ) jego zawartość jest konkatenacją plików o tej samej nazwie w kategoriach system/sepolicy/ i BOARDS_SEPOLICY_DIRS .
  • 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, które generują plik zasad SELinux dla systemu Android 7.x.
    Rysunek 2 . Plik polityki SELinux

Pliki SELinux

Po kompilacji urządzenia z systemem Android 7.x i starszym zazwyczaj zawierają następujące pliki związane z SELinux:

  • selinux_version
  • sepolicy: binarne wyjście po połączeniu plików strategii (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 Implementacja SELinux .

Inicjalizacja SELinux

Po uruchomieniu systemu SELinux jest w trybie zezwalającym (a nie w trybie wymuszania). Proces inicjowania 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 zachowaniu kompatybilności.

Sepolityka platformy jest dalej podzielona na część prywatną platformy i część publiczną platformy w celu eksportowania określonych typów i atrybutów do twórców zasad dostawcy. Publiczne typy/atrybuty platformy są gwarantowane jako stabilne interfejsy API dla danej wersji platformy. Zgodność z poprzednimi publicznymi typami/atrybutami platformy można zagwarantować dla kilku wersji przy użyciu plików mapowania platformy.

Sepolityka publiczna platformy

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

Typy są wersjonowane zgodnie z wersją zasad, zgodnie z którą są zapisywane pliki dostawcy, zdefiniowanej przez zmienną kompilacji PLATFORM_SEPOLICY_VERSION . Wersjonowane zasady publiczne są następnie dołączane do zasad dostawcy i (w swojej oryginalnej formie) do zasad platformy. W związku z tym ostateczna zasada obejmuje zasady prywatnej platformy, zasady publiczne bieżącej platformy, zasady dotyczące poszczególnych urządzeń oraz zasady publiczne z wersjami odpowiadające wersji platformy, na podstawie której napisano zasady dotyczące urządzeń.

Sepolityka prywatna platformy

Prywatna sepolityka platformy obejmuje wszystko, co jest zdefiniowane w /system/sepolicy/private . Ta część zasad określa typy, uprawnienia i atrybuty tylko dla platformy, wymagane do działania platformy. Nie są one eksportowane do twórców zasad vendor/device . Twórcy zasad nieplatformowych nie mogą pisać swoich rozszerzeń zasad na podstawie typów/atrybutów/reguł zdefiniowanych w zasadach prywatnych platformy. Co więcej, zasady te mogą być modyfikowane lub mogą zniknąć w ramach aktualizacji dotyczącej samego frameworka.

Mapowanie prywatne platformy

Mapowanie prywatne platformy obejmuje instrukcje dotyczące zasad, które mapują atrybuty uwidocznione w zasadach publicznych platformy poprzednich wersji platformy na konkretne typy używane w bieżących zasadach publicznych platformy. Gwarantuje to, że zasady dostawcy, które zostały napisane na podstawie publicznych atrybutów platformy z poprzednich wersji publicznych zasad sepolityki platformy, będą nadal działać. Wersjonowanie opiera się na zmiennej build PLATFORM_SEPOLICY_VERSION ustawionej w AOSP dla danej wersji platformy. Dla każdej poprzedniej wersji platformy, od której oczekuje się, że ta platforma będzie akceptować zasady dostawcy, istnieje osobny plik mapowania. Aby uzyskać więcej informacji, zobacz Zgodność .

Android 11 i nowszy

system_ext i sepolicy produktów

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

Polityka publiczna jest eksportowana do dostawcy. Typy i atrybuty stają się stabilnym interfejsem API, a zasady dostawcy mogą odwoływać się do typów i atrybutów w zasadach publicznych. Typy są wersjonowane zgodnie z PLATFORM_SEPOLICY_VERSION , a wersjonowane zasady są dołączone do zasad dostawcy. Oryginalna polityka jest dołączona do każdej partycji system_ext i produktu.

Polityka prywatna zawiera typy system_ext-only i product-only, uprawnienia oraz atrybuty wymagane do działania system_ext i partycji produktu. Polityka prywatności jest niewidoczna dla dostawcy, co oznacza, że ​​zasady te są wewnętrzne i można je modyfikować.

system_ext i mapowanie produktu

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

  • Aby zainstalować plik mapowania dla system_ext, umieść plik cil zawierający żądane informacje o mapowaniu do {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.

    Polityka budowania SELinux

    Zasady SELinux w systemie Android 8.0 są tworzone przez połączenie elementów z /system i /vendor . Logika odpowiedniego ustawienia znajduje się w /platform/system/sepolicy/Android.mk .

    Polityka istnieje w następujących lokalizacjach:

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

    System kompilacji przyjmuje te zasady i tworzy komponenty zasad system, system_ext, produktu, dostawcy i odm na odpowiedniej partycji. Kroki obejmują:

    1. Konwersja polityk do formatu SELinux Common Intermediate Language (CIL), w szczególności:
      1. polityka platformy publicznej (system + system_ext + produkt)
      2. połączone polityka prywatna + publiczna
      3. publiczny + dostawca i zasada BOARD_SEPOLICY_DIRS
    2. Wersjonowanie zasad udostępnianych przez publiczne w ramach zasad dostawcy. Dokonuje się przy użyciu utworzonej publicznej polityki CIL w celu poinformowania połączonej polityki public + dostawca + BOARD_SEPOLICY_DIRS o tym, które części muszą zostać przekształcone w atrybuty, które zostaną połączone z polityką platformy.
    3. Tworzenie pliku mapowania łączącego platformę i części dostawcy. Początkowo łączy to tylko 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, umożliwiając zgodność z polityką dostawcy odnoszącą się do 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 strategii binarnej.

    Wstępnie skompilowana polityka SELinux

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

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

    • Oba /system/etc/selinux/plat_sepolicy_and_mapping.sha256 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 jest inny, init wraca do ścieżki kompilacji na urządzeniu. Zobacz system/core/init/selinux.cpp , aby uzyskać więcej informacji.