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 SoC 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 ponieważ modułowe pliki zasad SELinux są przechowywane na partycjach /vendor, proces init musi wcześniej zamontować partycje system i vendor, aby móc odczytać z nich pliki SELinux i połączyć je z głównymi plikami SELinux w katalogu system (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 projektulibselinuxwraz 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,checkmoduleidispol). 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 w system/sepolicy znajdziesz w artykule Pliki kluczy.
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 BOARD_SEPOLICY_DIRS dotyczącym konkretnego urządzenia.Boardconfig.mk Ta globalna zmienna kompilacji zawiera listę katalogów, które określają kolejność wyszukiwania dodatkowych plików zasad.
Na przykład dostawca układu SoC i producent ODM mogą dodać po jednym katalogu – jeden z ustawieniami specyficznymi dla układu 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/sepolicyBOARD_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.confjest generowany przez połączenie plikówsecurity_classes,initial_sids,*.te,genfs_contextsiport_contextsw tej kolejności. - W przypadku każdego pliku (np.
security_classes) jego zawartość jest konkatenacją plików o tej samej nazwie w katalogachsystem/sepolicy/iBOARDS_SEPOLICY_DIRS. policy.confjest wysyłany do kompilatora SELinux w celu sprawdzenia składni i kompilowany do formatu binarnego jakosepolicyna 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_versionsepolicy: dane binarne po połączeniu plików zasad (np.security_classes,initial_sidsi*.te)file_contextsproperty_contextsseapp_contextsservice_contextssystem/etc/mac_permissions.xml
Więcej informacji znajdziesz w artykule Implementowanie SELinux.
Inicjalizacja SELinux
Po uruchomieniu systemu SELinux działa w trybie zezwalającym (a nie w trybie egzekwowania). Proces init wykonuje te zadania:
- Wczytuje
sepolicyplikó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ą stabilnymi interfejsami API w przypadku danej wersji platformy. Zgodność z poprzednimi typami/atrybutami publicznymi 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 tego ustawienia znajduje się w
/platform/system/sepolicy/Android.bp.
Zasady te obowiązują w tych lokalizacjach:
| Lokalizacja | Zawiera |
|---|---|
system/sepolicy/public |
Platform sepolicy API |
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ć (dostawcy mogą je zignorować) |
BOARD_SEPOLICY_DIRS |
Vendor sepolicy |
BOARD_ODM_SEPOLICY_DIRS (Android 9 lub nowszy) |
ODM sepolicy |
SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS (Android 11 lub nowszy) |
system_ext sepolicy API |
SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS (Android 11 lub nowszy) |
system_ext szczegóły implementacji (dostawcy mogą je zignorować); |
PRODUCT_PUBLIC_SEPOLICY_DIRS (Android 11 lub nowszy) |
Product sepolicy API |
PRODUCT_PRIVATE_SEPOLICY_DIRS (Android 11 lub nowszy) |
Szczegóły implementacji usługi (dostawcy mogą je zignorować) |
System kompilacji pobiera te zasady i tworzy komponenty zasad system, system_ext, product, vendor i odm w odpowiedniej partycji. Kroki obejmują:
- Przekonwertuj zasady na format SELinux Common Intermediate Language (CIL), a w szczególności:
- Zasady dotyczące platform publicznych (
system,system_ext,product) - Połączona polityka prywatności i polityka publiczna
- Zasady publiczne, zasady dostawcy i zasady
BOARD_SEPOLICY_DIRS
- Zasady dotyczące platform publicznych (
- Wersja zasad udostępnionych publicznie w ramach zasad dostawcy.
Wygenerowane publiczne zasady CIL posłużą do określenia, które części połączonych zasad publicznych, zasad dostawcy i zasad
BOARD_SEPOLICY_DIRSmuszą zostać przekształcone w atrybuty połączone z zasadami platformy. - Utwórz plik mapowania łączący 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.
- Połącz pliki zasad (opisz rozwiązania na urządzeniu i wstępnie skompilowane).
- Połącz zasady mapowania, platformy i dostawcy.
- Skompiluj wyjściowy plik binarny 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 zasadach publicznych są stabilnymi interfejsami API dla danej wersji platformy. Stanowi to część zasad bezpieczeństwa, która jest eksportowana 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 dostawców ani autorów zasad dotyczących urządzeń. Osoby piszące zasady spoza platformy nie mogą tworzyć rozszerzeń zasad na podstawie typów, atrybutów i reguł zdefiniowanych w prywatnych zasadach bezpieczeństwa platformy. Ponadto te reguły można modyfikować lub mogą one 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 w poprzednich wersjach 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 artykule Zgodność zasad.
Android 11 lub nowszy
W tej sekcji opisujemy, jak tworzone są zasady SELinux w Androidzie 11 i nowszym.
system_ext i zasady bezpieczeństwa produktu
W Androidzie 11 dodano zasady system_ext i product. Podobnie jak w przypadku zasad platformy, zasady system_ext i zasady product 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. Pierwotne zasady są uwzględnione w każdej z partycji system_ext i product.
Zasady ochrony prywatności zawierają typy, uprawnienia i atrybuty wymagane tylko w przypadku system_ext i tylko w przypadku product, które są niezbędne do działania funkcji podziału system_ext i product.
Zasady prywatności są niewidoczne dla dostawcy, co oznacza, że te reguły są wewnętrzne i można je modyfikować.
mapowanie system_ext i product;
system_ext i product mogą eksportować wyznaczone typy publiczne do dostawcy. Każdy partner jest jednak odpowiedzialny za zachowanie zgodności. Aby zapewnić zgodność, partnerzy mogą udostępniać własne pliki mapowania, które mapują atrybuty z wersjami z poprzednich wersji na konkretne typy używane w bieżącej publicznej wersji sepolicy:
- Aby zainstalować plik mapowania dla
system_ext, umieść plik CIL zawierający odpowiednie informacje o mapowaniu w{SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil, a następnie dodajsystem_ext_{ver}.cildoPRODUCT_PACKAGES. - Aby zainstalować plik mapowania dla
product, umieść plik CIL zawierający odpowiednie informacje o mapowaniu w{PRODUCT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil, a następnie dodajproduct_{ver}.cildoPRODUCT_PACKAGES.
Zapoznaj się z przykładem, w którym dodano plik mapowania partycji product 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 do postaci binarnej, którą można wczytać do jądra. Kompilacja zajmuje trochę czasu (zwykle 1–2 sekundy), dlatego 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 haszami 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.sha256i/{partition}/etc/selinux/precompiled_sepolicy.plat_sepolicy_and_mapping.sha256istnieją i są identyczne. - Nie istnieją 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. lub oba istnieją i są identyczne. - Nie istnieją zarówno
/product/etc/selinux/product_sepolicy_and_mapping.sha256, jak i/{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.