Na tej stronie dowiesz się, jak tworzone są zasady SELinux. Zasady SELinux są tworzone na podstawie połączenia podstawowych zasad AOSP (platformy) i zasad dotyczących konkretnego urządzenia (dostawcy). Proces tworzenia zasad SELinux w przypadku Androida 4.4–7.0 polegał na scalaniu wszystkich fragmentów sepolicy, a następnie generowaniu monolitycznych plików w katalogu głównym. Oznaczało to, że dostawcy układów SOC i producenci ODM modyfikowali boot.img
(w przypadku urządzeń innych niż A/B) lub system.img
(w przypadku urządzeń A/B) za każdym razem, gdy zmieniano zasady.
W Androidzie 8.0 i nowszym zasady platformy i dostawcy są tworzone oddzielnie.
Producenci układów scalonych i OEM mogą aktualizować swoje części zasad, tworzyć obrazy (np. vendor.img
i boot.img
), a następnie aktualizować te obrazy niezależnie od aktualizacji platformy.
Jednak modułowe pliki zasad SELinux są przechowywane na partycjach /vendor
, dlatego proces init
musi wcześniej zamontować partycje systemową i dostawcy, aby móc odczytać z nich pliki SELinux i połączyć je z głównymi plikami SELinux w katalogu systemowym (przed załadowaniem ich do jądra).
Pliki źródłowe
Logika tworzenia SELinux znajduje się w tych plikach:
-
external/selinux
: zewnętrzny projekt SELinux, używany do tworzenia 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. Więcej informacji znajdziesz w sekcjiexternal/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 SELinux w Androidzie, w tym konteksty i pliki zasad. Znajduje się tu też główna logika kompilacji sepolicy (system/sepolicy/Android.mk
).
Więcej informacji o plikach znajdziesz w sekcji system/sepolicy
Wdrażanie SELinux.
Android 7.x i starsze
W tej sekcji opisujemy, jak tworzone są zasady SELinux w Androidzie 7.x i starszych wersjach.
Proces kompilacji w przypadku Androida 7.x i starszych wersji
Zasady SELinux są tworzone przez połączenie podstawowych zasad AOSP z dostosowaniami specyficznymi dla urządzenia. Połączone zasady są następnie przekazywane do kompilatora zasad i różnych narzędzi sprawdzających. Dostosowywanie do konkretnego urządzenia odbywa się za pomocą zmiennej BOARD_SEPOLICY_DIRS
zdefiniowanej w pliku Boardconfig.mk
dotyczącym konkretnego urządzenia. Ta globalna zmienna kompilacji zawiera listę katalogów, które określają kolejność wyszukiwania dodatkowych plików zasad.
Na przykład dostawca SoC i ODM mogą dodać po jednym katalogu – jeden z ustawieniami specyficznymi dla SoC, a drugi z ustawieniami specyficznymi dla urządzenia – aby wygenerować końcowe 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:

Rysunek 1. Logika kompilacji SELinux.
Plik sepolicy
składa się z kilku plików źródłowych:
- Zwykły tekst
policy.conf
jest generowany przez połączenie plikówsecurity_classes
,initial_sids
,*.te
,genfs_contexts
iport_contexts
w tej kolejności. - W przypadku każdego pliku (np.
security_classes
) jego zawartość jest połączeniem plików o tej samej nazwie w katalogachsystem/sepolicy/
iBOARDS_SEPOLICY_DIRS
. policy.conf
jest wysyłany do kompilatora SELinux w celu sprawdzenia składni i kompilowany do formatu binarnego jakosepolicy
na urządzeniu.Rysunek 2. plik zasad SELinux,
Pliki SELinux
Po skompilowaniu urządzenia z Androidem 7.x i starszym zwykle zawierają te pliki związane z SELinux:
selinux_version
- sepolicy: dane binarne po połączeniu plików zasad (np.
security_classes
,initial_sids
i*.te
); file_contexts
property_contexts
seapp_contexts
service_contexts
system/etc/mac_permissions.xml
Więcej informacji znajdziesz w artykule Wdrażanie SELinux.
Inicjalizacja SELinux
Po uruchomieniu systemu SELinux działa w trybie zezwalającym (a nie w trybie egzekwowania). Proces init wykonuje te zadania:
- Wczytuje
sepolicy
plików z dysku RAM do jądra za pomocą/sys/fs/selinux/load
. - Przełącza SELinux w tryb egzekwowania.
- Uruchamia
re-exec()
, aby zastosować do siebie regułę domeny SELinux.
Aby skrócić czas rozruchu, jak najszybciej wykonaj proces re-exec()
na urządzeniuinit
.
Android 8.0 lub nowszy
W Androidzie 8.0 zasady SELinux są podzielone na komponenty platformy i dostawcy, co umożliwia niezależne aktualizowanie zasad platformy i dostawcy przy zachowaniu zgodności.
Zasady platformy są dodatkowo dzielone na części prywatną i publiczną, aby eksportować określone typy i atrybuty do twórców zasad dostawców. Gwarantujemy, że publiczne typy i atrybuty platformy będą utrzymywane jako stabilne interfejsy API w przypadku danej wersji platformy. Zgodność z poprzednimi publicznymi typami/atrybutami platformy można zagwarantować w przypadku kilku wersji za pomocą plików mapowania platformy.
Proces kompilacji w Androidzie 8.0
Zasady SELinux w Androidzie 8.0 powstają przez połączenie fragmentów z /system
i /vendor
. Logika prawidłowego konfigurowania tej funkcji znajduje się w
/platform/system/sepolicy/Android.mk
.
Zasady obowiązują w tych lokalizacjach:
Lokalizacja | Zawiera |
---|---|
system/sepolicy/public |
Interfejs API sepolicy platformy |
system/sepolicy/private |
Szczegóły wdrożenia na platformie (dostawcy mogą je zignorować) |
system/sepolicy/vendor |
Pliki zasad i kontekstu, których dostawcy mogą używać (mogą je zignorować, jeśli chcą). |
BOARD_SEPOLICY_DIRS |
Vendor sepolicy |
BOARD_ODM_SEPOLICY_DIRS (Android 9 lub nowszy) |
Odm sepolicy |
SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS (Android 11 lub nowszy) |
Interfejs API sepolicy w system_ext |
SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS (Android 11 lub nowszy) |
Szczegóły implementacji system_ext (dostawcy mogą je zignorować) |
PRODUCT_PUBLIC_SEPOLICY_DIRS (Android 11 lub nowszy) |
Interfejs API sepolicy produktu |
PRODUCT_PRIVATE_SEPOLICY_DIRS (Android 11 lub nowszy) |
Szczegóły implementacji produktu (dostawcy mogą zignorować) |
System kompilacji pobiera te zasady i tworzy komponenty zasad system, system_ext, product, vendor i odm w odpowiedniej partycji. Kroki obejmują:
- Konwertowanie zasad na format SELinux Common Intermediate Language (CIL), a w szczególności:
- zasady platformy publicznej (system + system_ext + product)
- połączone zasady prywatne i publiczne,
- public + vendor i
BOARD_SEPOLICY_DIRS
policy
- Wersjonowanie zasad udostępnianych publicznie w ramach zasad dostawcy.
Odbywa się to poprzez wykorzystanie utworzonej publicznej polityki CIL do określenia, które części połączonej polityki publicznej + dostawcy +
BOARD_SEPOLICY_DIRS
muszą zostać przekształcone w atrybuty, które zostaną połączone z polityką platformy. - Utwórz plik mapowania, który połączy części platformy i sprzedawcy. Początkowo ta funkcja tylko łączy typy z zasad publicznych z odpowiednimi atrybutami w zasadach dostawcy. Później będzie też stanowić podstawę pliku utrzymywanego w przyszłych wersjach platformy, co umożliwi zgodność z zasadami dostawcy kierowanymi na tę wersję platformy.
- Łączenie plików zasad (opis rozwiązań na urządzeniu i wstępnie skompilowanych).
- Połącz zasady dotyczące mapowania, platformy i dostawcy.
- Skompiluj wyjściowy binarny plik zasad.
Platform public sepolicy
Publiczna zasada SEPolicy platformy obejmuje wszystko, co jest zdefiniowane w sekcji
system/sepolicy/public
. Platforma może założyć, że typy i atrybuty zdefiniowane w ramach zasad publicznych są stabilnymi interfejsami API dla danej wersji platformy. Stanowi to część zasad sepolicy eksportowaną przez platformę, na której deweloperzy zasad dostawcy (czyli urządzenia) mogą pisać dodatkowe zasady dotyczące konkretnego urządzenia.
Typy są wersjonowane zgodnie z wersją zasad, w odniesieniu do której pisane są pliki dostawcy, zdefiniowaną przez zmienną kompilacji PLATFORM_SEPOLICY_VERSION
. Wersja zasad publicznych jest następnie dołączana do zasad dostawcy i (w oryginalnej formie) do zasad platformy. W związku z tym ostateczne zasady obejmują zasady platformy prywatnej, publiczne zasady bezpieczeństwa platformy bieżącej, zasady dotyczące urządzenia i wersjonowane zasady publiczne odpowiadające wersji platformy, na podstawie której zostały opracowane zasady dotyczące urządzenia.
Platform private sepolicy
Prywatne zasady bezpieczeństwa platformy obejmują wszystko, co zostało zdefiniowane w sekcji
/system/sepolicy/private
. Ta część zasad określa typy, uprawnienia i atrybuty wymagane do działania platformy. Nie są one eksportowane do vendor/device
. Osoby piszące zasady spoza platformy nie mogą tworzyć rozszerzeń zasad na podstawie typów, atrybutów ani reguł zdefiniowanych w prywatnych zasadach bezpieczeństwa platformy. Ponadto te reguły mogą zostać zmodyfikowane lub zniknąć w ramach aktualizacji samego frameworka.
Prywatne mapowanie platformy
Prywatne mapowanie platformy obejmuje oświadczenia o zasadach, które mapują atrybuty udostępniane w publicznych zasadach platformy poprzednich wersji platformy na konkretne typy używane w bieżących publicznych zasadach platformy sepolicy. Dzięki temu zasady dostawcy, które zostały napisane na podstawie publicznych atrybutów platformy z poprzednich wersji publicznych zasad bezpieczeństwa platformy, nadal działają. Wersjonowanie opiera się na zmiennej kompilacji PLATFORM_SEPOLICY_VERSION
ustawionej w AOSP dla danej wersji platformy. Dla każdej poprzedniej wersji platformy, z której ta platforma ma akceptować zasady dostawcy, istnieje osobny plik mapowania. Więcej informacji znajdziesz w sekcji Zgodność.
Android 11 lub nowszy
system_ext i zasady bezpieczeństwa produktu
W Androidzie 11 dodano zasady system_ext i zasady dotyczące produktów. Podobnie jak zasady platformy, zasady system_ext i zasady dotyczące produktów są podzielone na zasady publiczne i zasady prywatne.
Zasady publiczne są eksportowane 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ą uwzględniane w zasadach dostawcy. Oryginalne zasady są uwzględniane w każdej partycji system_ext i product.
Polityka prywatności zawiera typy, uprawnienia i atrybuty wymagane tylko w przypadku system_ext i tylko w przypadku produktu, które są niezbędne do działania partycji system_ext i partycji produktu. Zasady prywatności są niewidoczne dla dostawcy, co oznacza, że są to reguły wewnętrzne, które można modyfikować.
Mapowanie system_ext i product
system_ext i product mogą eksportować wyznaczone typy publiczne do vendor. Jednak każdy partner ponosi odpowiedzialność za zachowanie zgodności. Aby zapewnić zgodność, partnerzy mogą dostarczać własne pliki mapowania, które mapują wersjonowane atrybuty poprzednich wersji na konkretne typy używane w bieżącej publicznej polityce bezpieczeństwa.
- 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 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, w którym dodano plik mapowania partycji produktów urządzenia redbull.
Wstępnie skompilowane zasady SELinux
Zanim init
włączy SELinux, init
zbiera wszystkie pliki CIL z partycji (system
, system_ext
, product
, vendor
i odm
) i kompiluje je w zasady binarne, czyli format, który można wczytać do jądra. Kompilacja zajmuje trochę czasu (zwykle 1–2 sekundy), więc pliki CIL są wstępnie kompilowane w czasie kompilacji i umieszczane w folderze /vendor/etc/selinux/precompiled_sepolicy
lub /odm/etc/selinux/precompiled_sepolicy
wraz z hashami SHA256 wejściowych plików CIL. W czasie działania init
sprawdza, czy któryś z plików zasad został zaktualizowany, porównując hasze. Jeśli nic się nie zmieniło, init
wczytuje wstępnie skompilowane zasady. Jeśli nie, init
kompiluje go na bieżąco i używa zamiast wstępnie skompilowanego.
W szczególności wstępnie skompilowane zasady są używane, jeśli spełnione są wszystkie te warunki: W tym przypadku {partition}
oznacza partycję, w której znajduje się wstępnie skompilowana zasada: vendor
lub odm
.
-
Oba elementy
/system/etc/selinux/plat_sepolicy_and_mapping.sha256
i/{partition}/etc/selinux/precompiled_sepolicy.plat_sepolicy_and_mapping.sha256
istnieją i są identyczne. -
Nie istnieją ani
/system_ext/etc/selinux/system_ext_sepolicy_and_mapping.sha256
, ani/{partition}/etc/selinux/precompiled_sepolicy.system_ext_sepolicy_and_mapping.sha256
. lub oba istnieją i są identyczne. -
Nie istnieją ani
/product/etc/selinux/product_sepolicy_and_mapping.sha256
, ani/{partition}/etc/selinux/precompiled_sepolicy.product_sepolicy_and_mapping.sha256
. lub oba istnieją i są identyczne.
Jeśli któraś z nich się różni, init
wraca do ścieżki kompilacji na urządzeniu. Więcej informacji znajdziesz w sekcji
system/core/init/selinux.cpp
.