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 projektulibselinux
wraz z pewnymi dostosowaniami specyficznymi dla Androida. Aby uzyskać szczegółowe informacje, zobaczexternal/selinux/README.android
. -
external/selinux/libsepol
: -
external/selinux/checkpolicy
: Kompilator zasad SELinux (pliki wykonywalne hosta:checkpolicy
,checkmodule
idispol
). Zależy odlibsepol
.
-
-
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:
Plik sepolicy
składa się z wielu plików źródłowych:
- Plik
policy.conf
w postaci zwykłego tekstu jest generowany przez połączeniesecurity_classes
,initial_sids
, plików*.te
, plikówgenfs_contexts
iport_contexts
w tej kolejności. - Dla każdego pliku (takiego jak
security_classes
) jego zawartość jest konkatenacją plików o tej samej nazwie w katalogachsystem/sepolicy/
iBOARDS_SEPOLICY_DIRS
. - Plik
policy.conf
jest wysyłany do kompilatora SELinux w celu sprawdzenia składni i kompilowany do formatu binarnego jakosepolicy
na urządzeniu.
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 dodajsystem_ext_{ver}.cil
doPRODUCT_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 dodajproduct_{ver}.cil
doPRODUCT_PACKAGES
. Zapoznaj się z przykładem , który dodaje plik mapowania partycji produktu urządzenia Redbull. - Konwertowanie polityk do formatu SELinux Common Intermediate Language (CIL), w szczególności:
- Polityka platformy publicznej (system + system_ext + produkt)
- połączona polityka prywatna + publiczna
- polityka publiczna + dostawca i
BOARD_SEPOLICY_DIRS
- 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. - 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.
- Łączenie plików zasad (opisz zarówno rozwiązania na urządzeniu, jak i rozwiązania prekompilowane).
- Połącz zasady mapowania, platformy i dostawcy.
- Skompiluj wyjściowy plik zasad binarnych.
- 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.
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ą:
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
.
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
.